Rust 如何对包含原始指针的结构强制执行生存期?

Rust 如何对包含原始指针的结构强制执行生存期?,rust,lifetime,borrow-checker,Rust,Lifetime,Borrow Checker,编者按:此代码不再在Rust 1.0中编译,错误为参数“a”从未使用过。此错误的原因正是由于下面演示的问题,因此(更新的)解决方案仍然适用 它的寿命不应该是b?我预计会出现编译错误,因为生存期'a比MutPtr的生存期长。我想您要查找的是core::marker::PhantomData(也可以在std::marker::PhantomData中找到)。 发生的情况是,编译器没有为指针变量分配任何生存期,因此编译器不知道如何约束结构的生存期 方法是添加一个标记PhantomData, } 恳求{

编者按:此代码不再在Rust 1.0中编译,错误为
参数“a”从未使用过
。此错误的原因正是由于下面演示的问题,因此(更新的)解决方案仍然适用


它的寿命不应该是
b
?我预计会出现编译错误,因为生存期
'a
MutPtr的生存期长。我想您要查找的是
core::marker::PhantomData
(也可以在
std::marker::PhantomData
中找到)。 发生的情况是,编译器没有为指针变量分配任何生存期,因此编译器不知道如何约束结构的生存期

方法是添加一个标记
PhantomData,
}
恳求{

fn new(value:&'a mut T T)->mutpt您故意将值存储为
*mut T
,而不是
&'a mut T
?@Dogbert yes,因为我希望在同一范围内有多个可变指针。(仅用于实验)几分钟前我也做了同样的事情。问题是,一旦我做了
MutPtr::new(&mutb)之后,
b.v
就不再工作了
。我假设
ContravariantLifetime
保存变量是可变借用的?错误是
无法使用b.v,因为它是可变借用的
我猜问题是因为您正在尝试执行的操作(创建对同一内容的两个可变引用)显式标记为。因此,您可能无法提供实现这种行为的安全接口,或者至少我不知道。@MaikKlein:您应该看看,它可以让您,例如,对
RefCell
有许多不可变的引用,您可以从中获得对内部的可变引用,如l只要一次只有一个活动的可变借阅。我想尝试ContrariantLifetime?我在哪里可以找到它?我需要在启用功能的情况下使用不稳定的rust吗?我需要使用库吗?
使用std::marker::ContrariantLifetime;
marker
ContrariantLifetime>中出现
错误ime
不久前被
std::marker::PhantomData
取代。
extern crate core;
use core::ops::{Deref, DerefMut};

struct MutPtr<'a, T> {
    ptr: *mut T,
}
impl<'a, T> MutPtr<'a, T> {
    fn new<'b>(value: &'b mut T) -> MutPtr<'b, T> {
        MutPtr { ptr: value }
    }
}
impl<'a, T> Deref for MutPtr<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        unsafe { &(*self.ptr) }
    }
}
impl<'a, T> DerefMut for MutPtr<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut (*self.ptr) }
    }
}
struct Bar {
    v: i32,
}

fn err<'a>() -> MutPtr<'a, Bar> {
    let mut b = Bar { v: 42 };
    MutPtr::new(&mut b) // Shouldn't this throw an error?
}

fn main() {
    let mut b = Bar { v: 42 };
    let mut ptr_b = MutPtr::new(&mut b);
    let mut ptr_b1 = MutPtr::new(&mut b);

    ptr_b.v = 10;
    println!("{}", b.v);
    ptr_b1.v = 21;
    println!("{}", b.v);
}
fn err<'a>() -> MutPtr<'a, Bar> {
    let mut b = Bar { v: 42 };
    MutPtr::new(&mut b) // Shouldn't this throw an error?
}
MutPtr::new(&mut b)
struct MutPtr<'a, T> {
    ptr: *mut T,
    _covariant: PhantomData<&'a ()>,
}

impl<'a, T> MutPtr<'a, T> {
    fn new(value: &'a mut T) -> MutPtr<'a, T> {
        MutPtr {
            ptr: value,
            _covariant: PhantomData,
        }
    }
}