My understanding:
iter()
: read only view of data inside collection.into_iter()
: writable and readable view of data inside collection.
(caveat : full access but moved from parent scope)iter_mut()
: writable view of data inside collection.
(caveat : full access but not moved from parent scope, similar to other gc collected languages)And just to differentiate datatypes returned from iter()
and iter_mut()
, we do &"Ferris"
and &mut"Ferris"
Working code :
fn main() {
let mut names = vec!["Bob", "Frank", "Ferris"];
for name in names.iter_mut() {
*name = match name {
&mut "Ferris" => "There is a rustacean among us!",
_ => "Hello!",
}
}
println!("names: {:?}", names);
}
Why the below code is not working.
fn main() {
let names = vec!["Bob", "Frank", "Ferris"];
for name in names.into_iter() {
*name = match name {
"Ferris" => "There is a rustacean among us!",
_ => "Hello",
};
println!("names: {:?}", names);
}
}
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
src/main.rs:6:25
|
6 | "Ferris" => "There is a rustacean among us!",
expected `str`, found `&str`
error[E0277]: the size for values of type `str` cannot be known at compilation time
src/main.rs:5:9
|
5 | *name = match name {
doesn't have a size known at compile-time
|
help: the trait `Sized` is not implemented for `str`
note: the left-hand-side of an assignment must have a statically known size
Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `playground` (bin "playground") due to 2 previous errors
I tried changing the &str
to String
using to_string()
inside match statement but it's not clear why this code is not working.
Types are not the same depending on your iteration.
In particular name in names.into_iter()
will not give you a mutable reference but the type inside collection names
, that is &str
.
Following code [playground]:
fn type_name<T>(_t: &T) -> &'static str {
std::any::type_name::<T>()
}
fn main() {
let mut names = vec!["Bob", "Frank", "Ferris"];
for name in names.iter_mut() {
println!("names: {:?} -> {}", name, type_name(&name));
}
for name in names.iter() {
println!("names: {:?} -> {}", name, type_name(&name));
}
for name in names.into_iter() {
println!("names: {:?} -> {}", name, type_name(&name));
}
}
will give you:
names: "Bob" -> &mut &str
names: "Frank" -> &mut &str
names: "Ferris" -> &mut &str
names: "Bob" -> &&str
names: "Frank" -> &&str
names: "Ferris" -> &&str
names: "Bob" -> &str
names: "Frank" -> &str
names: "Ferris" -> &str