Search code examples
stringrustgetter-setter

How can I get a String as a return from an Arc Mutex


Here is the code.

use std::sync::{ Arc, Mutex };

fn main() {
    let test_s = Test{ s: Arc::new(Mutex::new(String::new())) };
    test_s.setter(String::from("whatever"));
    println!("{}", test_s.getter())
}

struct Test {
    s: Arc<Mutex<String>>,
}

impl Test {
    pub fn getter(&self) -> String {
        *self.s.lock().unwrap() // Error occured here !
    }
    
    pub fn setter(&self, s: String) {
        *self.s.lock().unwrap() = s
    }
}

And here is the Error output

   Compiling playground v0.0.1 (/playground)
error[E0507]: cannot move out of dereference of `MutexGuard<'_, String>`
  --> src/main.rs:15:9
   |
15 |         *self.s.lock().unwrap()
   |         ^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait

For more information about this error, try `rustc --explain E0507`.
error: could not compile `playground` due to previous error

I can get the s value just use test_s.s.lock().unwrap(), and use it as a &str just with &test_s.s.lock().unwrap()

Is there an easy way to return a String?


Solution

  • You do not need to deref directly there (*), also you will need to Clone the String:

    ...
        pub fn getter(&self) -> String {
             self.s.lock().unwrap().clone()
        }
    ...
    

    Playground