Here is example code:
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);
});
}
Errors:
<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;
^~~~~~~~~~~~
The type of tuple is &(&u8, &mut collections::vec::Vec<u8>)
so I expect it to be unpackable with following:
let (&k, &mut v) = *t;
But
<anon>:10:28: 10:30 error: type `(&u8, &mut collections::vec::Vec<u8>)` cannot be dereferenced
<anon>:10 let (&k, &mut v) = *t;
^~
How to unpack it and use for mutable purposes?
Check out the error message:
expected `&(&u8, &mut collections::vec::Vec<u8>)`,
found `(_, _)`
(expected &-ptr,
found tuple) [E0308]
The compiler expects to match against a reference, but the code does not provide such. Change the binding to let &(&k, &mut v) = t
. Then you get a bunch of other errors:
Matching using &mut foo
means that foo
will have the &mut
stripped off, and then the resulting value will be moved to foo
. This is because it is a pattern match, just like how let Some(foo) = ...
"strips off" the Some
.
You can't move the Vec
because it's owned by the BTreeMap
, so you need to take a reference to it. This is done with the ref
keyword, not the &
operator.
Normally, you'd also do the pattern matching directly in the closure argument, not in a second variable.
Since map
transfers ownership of the item to the closure, you can just give that a mut
binding, no need for any references.
As k
is unused, it's idiomatic to replace the name with an underscore ( _
).
let idx = map.iter_mut().find(|&(k, ref v)| {
v.is_empty()
});
idx.map(|(_, mut v)| {
v.push(5);
});
use for mutable purposes
If you mean "how can I mutate the value in the closure to find
", the answer is "you can't". Find returns an immutable reference to the iterated item ( &Self::Item
):
fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where P: FnMut(&Self::Item) -> bool
Even though your Self::Item
might be a mutable reference, an immutable reference to a mutable reference is still immutable.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.