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;
^~
如何打开包装并将其用于可变目的?
最佳答案
查看错误消息:
expected `&(&u8, &mut collections::vec::Vec<u8>)`,
found `(_, _)`
(expected &-ptr,
found tuple) [E0308]
编译器希望与引用进行匹配,但是代码没有提供这种引用。将绑定(bind)更改为
let &(&k, &mut v) = t
。然后,您会收到许多其他错误:&mut foo
进行匹配意味着foo
将去除&mut
,然后将结果值移到foo
。这是因为它是一个模式匹配,就像let Some(foo) = ...
如何“剥离” Some
一样。 Vec
,因为它是BTreeMap
所拥有的,因此您需要对其进行引用。这是通过ref
关键字而不是&
运算符完成的。 map
将项目的所有权转移到了闭包中,所以您可以给mut
绑定(bind),而无需任何引用。 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
即使您的
Self::Item
可能是可变引用,对可变引用的不可变引用仍然是不可变的。关于dictionary - 如何从Rust中的迭代器解包BTreeMap项目元组?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37658848/