let mut v: Vec<String> = vec!["abc".to_string()];
for i in v {
let cmp = "abc".to_string();
v.retain(|x| x != cmp);
}
I get an error on the retain line: can't compare &std::string::String with std::string::String. This is expected since the retain lambda is passed a reference to each item and cmp is a String.
Howerver, if I capture the item by reference:
v.retain(|&x| x != cmp);
the actual type of x becomes String and not &&String as I would expect. How come? Thanks
You can think of this not as "capturing by something", but as "taking as something". In this case, the closure takes some reference to the object and assigns, or binds, the name x to that object.
Note that your code wouldn't compile as-is (playground) - for two reasons, but I'll focus on the first one:
error[E0507]: cannot move out of a shared reference
--> src/main.rs:7:19
|
7 | v.retain(|&x| x != cmp);
| ^-
| ||
| |data moved here
| |move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait
| help: consider removing the `&`: `x`
It means that, when binding the item behind the reference to the name, program must copy it - otherwise it'd have to "steal" it from the real owner; but the String, as any container, isn't copyable.