rust - 将 Arc<RwLock> 转换为 &mut

标签 rust

我正在尝试在可以通过引用进行变异的特征中获得一个值。问题是 String 值非常大并且可能被许多线程访问,所以我的解决方案看起来像这样:

trait MyTrait {
    fn name<'a>(&'a mut self) -> &'a mut String;
}

struct SimpleImpl {
    name: String
}

impl MyTrait for SimpleImpl {
    fn name<'a>(&'a mut self) -> &'a mut String {
        &mut self.name
    }
}

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

struct ParallelImpl {
    name: Arc<RwLock<String>>
}

impl MyTrait for ParallelImpl {
    fn name<'a>(&'a mut self) -> &'a mut String {
        self.name.get_mut().unwrap()
    }
}

fn main() {
    let mut a = SimpleImpl { name: String::from("simple") };
    let mut b = ParallelImpl { name: Arc::new(RwLock::new(String::from("parallel"))) };

    a.name().as_mut_str();
    b.name().as_mut_str();
}

编译失败

main2.rs:23:9: 23:18 error: cannot borrow immutable borrowed content as mutable
main2.rs:23         self.name.get_mut().unwrap()

为什么我不能调用 get_mut() 来解包 ArcRwLock

最佳答案

再看一下RwLock的界面.

get_mut 返回 LockResult<&mut T>这是一个守卫对象。破坏这个守卫会自动打开锁。

为了安全起见,&mut T您可以通过调用 unwrap() 获得on the guard 是从guard借用,即unwrap()的结果的生命周期受守卫的限制(因为守卫被摧毁后,锁被解锁)。

而在这里,你正在创建一个临时守卫并立即将其丢弃,因此引用的生命周期不能超过函数的生命周期...

恭喜 Rust! 在编译时阻止了另一场数据竞争 :)

关于rust - 将 Arc<RwLock> 转换为 &mut,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40915716/

相关文章:

casting - 如何将 Vec<&mut T> 转换为 Vec<&T>?

html - 编写 HTML 解析器时借用的值不够长

rust - 通过循环和 push() 或通过 collect() 创建一个充满顺序 u64 的大型 Vec 是否更快?

join - 如何加入两个Options<Vec<String>>

rust - xcb:在 EnterNotify 之后立即收到 LeaveNotify

rust - 如何在实现 Deref 的类型(例如 Box)内对值进行模式匹配,而不复制内容?

null - 我们应该使用 Option 还是 ptr::null 来表示 Rust 中的空指针?

rust - 有没有办法让 Rust 相信特定的关联类型与具体类型相同?

rust - 按位还是匹配?

logging - 是否可以覆盖类型的现有 Debug 实现?