直接看demo
let mut map = HashMap::new();
let mut is_new = false;
map.entry(1).or_insert({
is_new = true;
1
});
if is_new {
println!("is_new");
}
目的是想在map新增key的时候做一些处理,看起来很美好,编译通过了,但是多了警告
warning: value assigned to is_new
is never read
--> src\main.rs:133:13
纳尼?is_new明明用了啊而且控制台还打印了,当时心里还暗想难道是rust的bug?,带着疑问我在群里问了下,经过讨论最后“大头矮子”还原了真相,原来or_insert传的是值,并不是闭包,也就是我传了个表达式进去,is_new无论什么情况都会执行等于true,if is_new 就等同于if true 所以rust编译器认为is_new根本不需要才会有此警告,不得不说rust编译器真是强大,要是没这个警告我就掉坑里了,哈哈。 最后此问题解决方案可以调用or_insert_with。完美解决。
1
共 5 条评论, 1 页
评论区
写评论对以下内容的回复:
这段代码里,你知道这个闭包的
is_new = true;
必然会被执行,但编译器不知道,如果这个闭包没有执行,那么接下来println!("{}", is_new);
就读到了false
。写了个更小的例子,是不是
FnOnce
捕获环境的时候认为读了is_new
里面的值一次呢。对以下内容的回复:
为了证明我的推测
在
or_insert
前读一下is_new
也消除了warning。对以下内容的回复:
我还是不解,请教一下各位。
我能理解它是说一开始给
is_new
的false
没人读过。但是换了
or_insert_with
如下:那个
false
仍然没人读过,为什么就不warning了呢。这个还真是一个小坑。谢谢分享