So I have this code:
use std::sync::{Arc, Mutex};
fn main() {
let array = vec!("test", "work", "please");
let test = Arc::new(Mutex::new(array));
let getter = test.lock().unwrap();
println!("{:?}", getter);
for item in getter {
println!("{}", item);
}
}
it throws an error saying:
error[E0277]: `MutexGuard<'_, Vec<&str>>` is not an iterator
--> src/main.rs:11:17
|
11 | for item in getter {
| ^^^^^^ `MutexGuard<'_, Vec<&str>>` is not an iterator
|
= help: the trait `Iterator` is not implemented for `MutexGuard<'_, Vec<&str>>`
= note: required because of the requirements on the impl of `IntoIterator` for `MutexGuard<'_, Vec<&str>>`
Which, okay fine. But I am able to do let getter = test.lock().unwrap().len(); and that gets the length correctly. So why does it know its an array in the second case but not the first?
>Solution :
getter is a MutexGuard which implements Deref<Target = Vec<&str>>. When you call a method on it like .len(), it’s automatically dereferenced into the Vec because there’s no .len() method on MutexGuard. The same is not done automatically by a for loop. You can either force a manual dereference:
for item in &*getter {
or you can call .iter() on it which automatically dereferences it:
for item in getter.iter() {
Code:
use std::sync::{Arc, Mutex};
fn main() {
let array = vec!["test", "work", "please"];
let test = Arc::new(Mutex::new(array));
let getter = test.lock().unwrap();
println!("{:?}", getter);
for item in &*getter {
println!("{}", item);
}
for item in getter.iter() {
println!("{}", item);
}
}