use std::sync::{Arc, Mutex};
fn main() {
let w_vec = Arc::new(Mutex::new(vec![1, 2, 3]));
let v = w_vec.lock().unwrap();
print(*v);
}
fn print(v: Vec<i32>) {
println!("{:?}", v);
}
I got the following error:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:7:8
|
7 | print(*v);
| ^^ cannot move out of borrowed content
error: aborting due to previous error
error: Could not compile `blah`.
You can't "move out" of that. It would mean w_vec is invalid state.
You can either make print take a reference: fn print(v : &[i32]) and call it as print(v.as_slice()) or if you really want to move out the stuff from w_vec use replace in std::mem - Rust to substitute it with a new vec, so that w_vec state is valid.
If the compiler let you do this directly, then the next caller to lock the mutex would see undefined memory.
But both types have ways to move by proving you're the sole owner. Arc::try_unwrap will attempt this, succeeding only if the reference count is 1 (just you). Then Mutex::into_inner can move from that into the inner content.
As far as I can see you don't need to move the content out of the Arc. Instead you can pass the vector to print by reference. This version of the code allows you to print the vector more than once.
// with a copy
let built_words: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(vec![]));
let result: Vec<String> = built_words.lock().unwrap().clone();
// using drain
let mut locked_result = built_words.lock().unwrap();
let mut result: Vec<String> = vec![];
result.extend(locked_result.drain(..));
Please refrain from replying directly to a very old topic; instead create a new topic which links to this one if you have questions.
What you have posted does not "move out" of the Arc<Mutex>, and instead clones the data. The intended way to move out of an Arc<Mutex<T>> is to use the following methods:
let x = Arc::new(Mutex::new(Vec::<()>::new()));
let w = Arc::try_unwrap(x).unwrap().into_inner().unwrap();