use std::marker;
use std::ops;
pub struct Shared<'r, T: 'r> {
    data: *mut T,
    _pd: marker::PhantomData<&'r T>,
}

impl<'r, T> Shared<'r, T> {
    pub fn new(value: T) -> Shared<'r, T> {
        let boxed = Box::new(value);
        Shared {
            data: Box::into_raw(boxed),
            _pd: marker::PhantomData,
        }
    }

    pub fn as_ref(&self) -> SharedRef<'r, T> {
        SharedRef {
            data: self.data,
            _pd: marker::PhantomData,
        }
    }
}

impl<'r, T> ops::Deref for Shared<'r, T> {
    type Target = T;
    fn deref(&self) -> &T {
        unsafe { &*self.data }
    }
}

pub struct SharedRef<'r, T: 'r> {
    data: *mut T,
    _pd: marker::PhantomData<&'r T>,
}

impl<'r, T> ops::Deref for SharedRef<'r, T> {
    type Target = T;
    fn deref(&self) -> &T {
        unsafe { &*self.data }
    }
}

impl<'r, T> Drop for Shared<'r, T> {
    fn drop(&mut self) {
        unsafe {
            Box::from_raw(self.data);
        }
    }
}

fn main() {
    let s = Shared::new(42);
    let s_ref = s.as_ref();
    {
        let s1 = s;
    }
    // lifetime should end here
    println!("{}", *s_ref);
}

我要表达的是BoxArc之间的混合。唯一拥有的指针,也能够给出引用。

问题是,即使当前有不可变的借用,我也希望能够移动Shared。在这种情况下,它应该是合法的,因为它是堆分配的。

问题是我不知道该如何表达。
fn main() {
    let s = Shared::new(42);
    let s_ref = s.as_ref();
    {
        let s1 = s;
    }
    // lifetime should end here
    println!("{}", *s_ref);
}

在这里,我将s移入生存期比以前短的范围。但是现在我将s移到s1之后,就不再可以访问s_ref了。因此,我想说的是,如果生存期没有变短,可以移动Shared

可以用Rust表示吗?

最佳答案

Rust允许您移出Shared的原因是您尚未将返回的SharedRef的生命周期与其绑定(bind):

pub fn as_ref(&self) -> SharedRef<'r, T> {
    SharedRef {
        data: self.data,
        _pd: marker::PhantomData,
    }
}

注释&self可解决以下问题:
pub fn as_ref(&'r self) -> SharedRef<'r, T> { .. }

我目前的理解是,这里的主要区别在于,这意味着SharedRef的生存期现在与self的借用生存期匹配,从而使借用仍然有效。实际上,它的生存期('r)不必与Shared中的生存期相同;它为借/还款提供了新的生命周期:
pub fn as_ref<'b>(&'b self) -> SharedRef<'b, T> { .. }

这也不允许移动。

至于问题的奖励部分,您想允许它一直移动到生命周期足够长的东西,我认为答案是否定的。我知道完全停止移动任何东西的唯一方法就是借用它,这将停止任何移动。

关于rust - 即使是一成不变的借贷,也有可能搬家吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39056626/

10-11 21:49