Here是示例代码:
use std::collections::BTreeMap;
fn main() {
let mut map: BTreeMap<u8, Vec<u8>> = BTreeMap::new();
let idx = map.iter_mut().find(|t| {
let (&k, &mut v) = t;
v.is_empty()
});
idx.map(|t| {
let (&k, &mut v) = t;
v.push(5);
});
}
错误:
<anon>:6:13: 6:25 error: mismatched types:
expected `&(&u8, &mut collections::vec::Vec<u8>)`,
found `(_, _)`
(expected &-ptr,
found tuple) [E0308]
<anon>:6 let (&k, &mut v) = t;
^~~~~~~~~~~~
元组的类型是&(&u8, &mut collections::vec::Vec<u8>)
所以我希望它可以通过以下方式解压缩:
let (&k, &mut v) = *t;
但是
<anon>:10:28: 10:30 error: type `(&u8, &mut collections::vec::Vec<u8>)` cannot be dereferenced
<anon>:10 let (&k, &mut v) = *t;
^~
如何解压缩并用于可变用途?
答案 0 :(得分:3)
查看错误消息:
expected `&(&u8, &mut collections::vec::Vec<u8>)`,
found `(_, _)`
(expected &-ptr,
found tuple) [E0308]
编译器期望与引用匹配,但代码不提供此类引用。将绑定更改为let &(&k, &mut v) = t
。然后你会得到一堆其他错误:
使用&mut foo
进行匹配意味着foo
将&mut
剥离,然后结果值将移动到{{1 }}。这是因为它是一种模式匹配,就像foo
“剥离”let Some(foo) = ...
一样。
您无法移动Some
,因为它归Vec
所有,因此您需要参考它。这是通过BTreeMap
关键字完成的,而不是ref
运算符。
通常,你也会在闭包参数中直接进行模式匹配,而不是在第二个变量中进行模式匹配。
由于&
会将项目的所有权转移到闭包,因此您只需提供map
绑定,无需任何参考。
由于mut
未使用,因此使用下划线(k
)替换名称是惯用的。
_
用于可变用途
如果你的意思是“如何将闭包中的值变为let idx = map.iter_mut().find(|&(k, ref v)| {
v.is_empty()
});
idx.map(|(_, mut v)| {
v.push(5);
});
”,答案是“你不能”。 Find返回对迭代项(find
)的不可变引用:
&Self::Item
即使你的fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where P: FnMut(&Self::Item) -> bool
可能是一个可变引用,对可变引用的不可变引用仍然是不可变的。