You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 13:03:30