微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Crystal:检测字典插入是否覆盖了一个键,但没有散列两次

如何解决Crystal:检测字典插入是否覆盖了一个键,但没有散列两次

Crystal 中将键插入到

screenshot

中的规范方式是什么,但如果映射之前确实存在则抛出错误。原则上,代码如下:

public class Program
{
    static void Main(string[] args)
    {
        var config = LoadConfiguration();
        var provider = ConfigureServices(config);

        ConfigureConsumers(provider);

        Console.ReadLine();
    }

    public static IConfiguration LoadConfiguration()
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json",optional: true,reloadOnChange: true);

        return builder.Build();
    }

    private static ServiceProvider ConfigureServices(IConfiguration configuration)
    {
        var services = new ServiceCollection()
            .AddTransient<IEmailSender,EmailSender>()
            .Configure<AuthMessageSenderOptions>(options => configuration.GetSection("SendGridEmailSettings").Bind(options))
            .AddEasyNetQ(configuration["QueueConnectionData"]);

        return services.BuildServiceProvider();
    }

    private static void ConfigureConsumers(ServiceProvider provider)
    {
        var autoSubscriber = new AutoSubscriber(provider.GetrequiredService<IBus>(),"SomePrefix")
        {
            AutoSubscriberMessagedispatcher = provider.GetrequiredService<IAutoSubscriberMessagedispatcher>()
        };

        autoSubscriber.Subscribe(new[] { Assembly.GetExecutingAssembly() });
        autoSubscriber.SubscribeAsync(new[] { Assembly.GetExecutingAssembly() });
    }
}

我想知道是否有可能不散列两次?我想出了这个想法,但恕我直言很难阅读:

map = Hash(String,Int32).new
if map.has_key?("foo")
  raise "Mapping already exists"
else
  map["foo"] = 42
end

(如果映射存在,Hash 返回旧值。否则,调用块的结果,即 map = Hash(String,Int32).new if map.put("foo",42) {} raise "Mapping already exists" end 并计算为 nil。)

有推荐的模式吗?

解决方法

性能方面,您已经找到了最佳解决方案。我可能会使用块调用被内联的事实来稍微重写它:

def update(hash,key,value)
  hash.put(key,value) { return }
  raise "Duplicate entry"
end

但是这里有一个重要的陷阱:哈希值仍然在错误条件下更新:

hash = {"foo" => "bar"}
update(hash,"baz","quux")
pp hash # => {"foo" => "bar","baz" => "quux"}
update(hash,"foo","hello") rescue puts "Failed updating foo" # => Failed updating foo
pp hash # => {"foo" => "hello","baz" => "quux"}

https://carc.in/#/r/bn1o

在不侵入内部 API 的情况下,我认为没有办法避免这种情况。实际上,哈希查找并不是很昂贵,毕竟它是为通过键查找值而优化的数据结构。尤其是因为您似乎对提高 API 没问题,这是一项成本更高的操作。所以就我个人而言,我会选择类似于你的第一个例子的东西。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。