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
?
CodePudding user response:
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()
}
...
CodePudding user response:
Alternatively return the MutextGuard
, which derefs to the underlying type. You won't have to clone the string. You won't need the setter
anymore. But you'll have to remember to drop the guard before using the getter
again.
use std::sync::{ Arc, Mutex, MutexGuard };
fn main() {
let test_s = Test{ s: Arc::new(Mutex::new(String::new())) };
{
let mut s = test_s.getter();
s.push_str("what");
// MutexGuard s is dropped here - lock is released
}
println!("{}", test_s.getter());
{
let mut s = test_s.getter();
*s = "whatever".to_string();
// MutexGuard s is dropped here - lock is released
}
println!("{}", test_s.getter());
}
struct Test {
s: Arc<Mutex<String>>,
}
impl Test {
pub fn getter(&self) -> MutexGuard<String> {
self.s.lock().unwrap()
}
}