rust - 从 Mutex 中同时借用引用和保护

标签 rust lifetime

我正在尝试封装一些代码以避免重复它,这些代码涉及从 Mutex 中借用数据以及随后的进一步操作(由于超出范围,我将其从这个问题中删除,但这是激励因素)。

以下示例代码提示 guard 的生命周期不够长。但这正是我在专门为此目的设计的结构中返回 guard 的原因。

这是借用检查器的限制吗?关于解决此问题的任何建议?

use std::sync::{Mutex,MutexGuard};
use std::ops::DerefMut;

pub struct InnerData {
    count: i32  // sample only
}

pub struct Data {
    pub inner_data: Mutex<InnerData>
}

pub struct BorrowedInnerData<'a> {
    pub inner_data: &'a mut InnerData,
    guard: MutexGuard<'a,InnerData>,
}

impl Data {
    pub fn borrow_inner_data<'a>(&'a mut self) -> BorrowedInnerData<'a> {
        let guard = self.inner_data.lock().unwrap();
        BorrowedInnerData {
            inner_data: guard.deref_mut(),
            guard: guard,
        }
    }
}

fn main() {
    let mut data = Data {
        inner_data: Mutex::new( InnerData {
            count: 5
        }),
    };

    let borrowed_inner_data = data.borrow_inner_data();
}

最佳答案

让我们看看 DerefMut trait :

pub trait DerefMut: Deref {
    fn deref_mut(&'a mut self) -> &'a mut Self::Target;
}

这意味着当deref_mut被调用时,将返回一个引用,该引用与被取消引用的值一样长。但是,您正在移动 guard当你把它移到 BorrowedInnerData .这意味着该值停止存在于一个内存位置并从一个新位置开始。作为Veedrac hints at ,完全有可能通过移动守卫,使引用无效。这会很糟糕并导致崩溃(在最好的情况下)。

但是,没有真正的理由保留 guardinner_data .因为DerefDerefMut , 一个 MutexGuard<InnerData>可以像&InnerData一样使用或 &mut InnerData .只需删除 inner_data从你的结构中保留 guard .

关于rust - 从 Mutex 中同时借用引用和保护,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32194269/

相关文章:

generics - 如果我在函数内部创建引用,如何将泛型类型与需要生命周期参数的特征绑定(bind)?

rust - 如何实现 ToString 特征以创建没有尾随逗号的逗号分隔字符串?

immutability - 我如何强制结构的字段在 Rust 中始终不可变?

arrays - 如何创建包含大型数组的结构体数组?

multithreading - 在 Rust 中创建两个对结构线程安全的可变引用

rust - 为什么生命周期对 slice::from_raw_parts 很重要?

rust - 与 Vec 相比,为什么 SmallVec 在存储具有生命周期的类型时具有不同的行为?

rust - 错误[E0277] : the type `[u32]` cannot be indexed by `u32`

c++ - std::optional<>::emplace() 是否会使对内部值的引用无效?

rust - 如何从函数返回反转的字符串?