如何从Arc<Mutex<String>>中返回String类型值?
Rust中Arc<Mutex> getter返回String的问题解决
问题场景
使用Arc<Mutex<String>>时,希望通过getter方法返回String类型值,现有代码编译报错:
示例代码
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() // 此处报错! } pub fn setter(&self, s: String) { *self.s.lock().unwrap() = s } }
报错信息
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
已知可以通过test_s.s.lock().unwrap()获取值,或&test_s.s.lock().unwrap()作为&str使用,需要简便方法返回String。
解决方法
方法1:克隆字符串(推荐,保留原数据)
String实现了Clone trait,直接调用clone()复制一份返回,原字符串仍保存在Mutex中:
pub fn getter(&self) -> String { self.s.lock().unwrap().clone() }
方法2:取出原字符串(会清空原数据)
如果不需要保留原字符串内容,用take()方法将原字符串替换为空字符串,并返回原字符串:
pub fn getter(&self) -> String { self.s.lock().unwrap().take() }
原因说明
原代码报错是因为MutexGuard作为智能指针,持有内部String的引用权限。直接解引用试图将String从MutexGuard中move出来时,MutexGuard生命周期未结束,Rust所有权规则不允许这种操作——move后MutexGuard管理的内存会失效,违反安全规则。而clone()是复制新的String,take()则是合法转移原字符串所有权同时留下空字符串,都符合内存安全要求。
内容的提问来源于stack exchange,提问作者linonon
相关产品推荐
相关产品推荐

