rust - 即使借用不可变的东西也有可能移动吗?

标签 rust

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 的原因是你没有绑定(bind)返回的生命周期 SharedRef对它:

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/

相关文章:

memory - 将字符串转换为 &strs 时,切片和显式重新借用之间有区别吗?

rust - 使用 Serde 从套接字反序列化以换行符分隔的 JSON

rust - 迭代两个不同长度的向量

generics - 使此函数通用时如何满足特征界限?

collections - 如何更新 BTreeSet 中的所有值?

timer - 有没有办法在特定时间或间隔安排任务?

rust - 有没有办法可以将 futures 0.1 转换为标准库 futures?

rust - 不能借用 "values"作为不可变的,因为它也被借用为可变的

rust - 如何通过宏获取声明的变量名和变量类型

multithreading - 在多个线程中改变共享可变变量