如何解决Crystal:检测字典插入是否覆盖了一个键,但没有散列两次
Crystal 中将键插入到 中的规范方式是什么,但如果映射之前确实存在则抛出错误。原则上,代码如下:
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"}
在不侵入内部 API 的情况下,我认为没有办法避免这种情况。实际上,哈希查找并不是很昂贵,毕竟它是为通过键查找值而优化的数据结构。尤其是因为您似乎对提高 API 没问题,这是一项成本更高的操作。所以就我个人而言,我会选择类似于你的第一个例子的东西。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。