Borrowing reference and guard together from a Mutex

浪子不回头ぞ 提交于 2019-12-10 15:47:40

问题


I'm trying to encapsulate some code to avoid repeating it, relating to borrowing data out of a Mutex and further operations thereupon (which I leave off of this question as out of scope, but are the motivating factors).

The following sample code complains that guard does not live long enough. But that is precisely why I'm returning guard in the structure designed expressly for that purpose.

Is this a limitation of the borrow checker? Any suggestions on working around this?

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();
}

回答1:


Let's look at the DerefMut trait:

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

This means that when deref_mut is called, a reference is returned that lives as long as the value being dereferenced. However, you are moving guard when you move it to BorrowedInnerData. This means that the value stops living at one memory location and starts at a new one. As Veedrac hints at, it's entirely possible that by moving the guard, you would invalidate the reference. This would be bad and lead to crashes (in the best case).

However, there's no real reason to keep guard and inner_data. Because of Deref and DerefMut, a MutexGuard<InnerData> can be used just like a &InnerData or &mut InnerData. Simply remove inner_data from your struct and keep guard.



来源:https://stackoverflow.com/questions/32194269/borrowing-reference-and-guard-together-from-a-mutex

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!