3

編集者注:このコードは、Rust 1.0 ではエラーでコンパイルされなくなりましたparameter `'a` is never used。このエラーの理由は、以下に示す問題が原因であるため、(更新された) 解決策は引き続き適用可能です。

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)

の寿命を持つべきではありませんbか?'aの有効期間よりも有効期間が長いため、コンパイル エラーが発生することが予想されましたMutPtr<'b, Bar>

4

1 に答える 1

5

あなたが探しているのはcore::marker::PhantomData( にもありますstd::marker::PhantomData) だと思います。何が起こるかというと、コンパイラーはポインター変数にライフタイムを割り当てないため、コンパイラーは構造体のライフタイムを制約する方法を知りません。

それを行う方法は、構造体にマーカーを追加することですPhantomData<&'a ()>。これにより、構造体全体の寿命が長くならない可能性があることがコンパイラーに通知されます (実際には、フィールドが含まれていなくても、フィールドがある'aふりをします)。MutPtr<'a, T>&'a ()

したがって、最終的に構造体は次のようになります。

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,
        }
    }
}

これにより、予想されるエラーが発生しますb does not live long enough

于 2015-01-14T10:41:55.743 に答える