Rust 1.0
各种标记类型已统一为一种:PhantomData
use std::ptr;
use std::marker::PhantomData;
struct Heap {
ptr: *const u8,
}
impl Heap {
fn new(c_ptr: *const u8) -> Heap {
Heap {
ptr: c_ptr
}
}
fn wrap_handle<'a>(&'a self, c_handle: *const u8) -> Handle<'a> {
Handle {
ptr: c_handle,
marker: PhantomData,
}
}
}
struct Handle<'a> {
ptr: *const u8,
marker: PhantomData<&'a ()>,
}
fn main() {
let longer_heap = Heap::new(ptr::null());
let handle = {
let shorter_heap = Heap::new(ptr::null());
let longer_handle = longer_heap.wrap_handle(ptr::null());
let shorter_handle = shorter_heap.wrap_handle(ptr::null());
// longer_handle // ok to return
// shorter_handle // error: `shorter_heap` does not live long enough
};
}
原答案
这是一个使用的例子ContravariantLifetime。我们将原始堆指针包装到一个结构中,然后将原始句柄指针包装到另一个结构中,从而重用堆的生命周期。
use std::ptr;
use std::marker::ContravariantLifetime;
struct Heap {
ptr: *const u8,
}
impl Heap {
fn new(c_ptr: *const u8) -> Heap {
Heap {
ptr: c_ptr
}
}
fn wrap_handle<'a>(&'a self, c_handle: *const u8) -> Handle<'a> {
Handle {
ptr: c_handle,
marker: ContravariantLifetime,
}
}
}
struct Handle<'a> {
ptr: *const u8,
marker: ContravariantLifetime<'a>,
}
fn main() {
let longer_heap = Heap::new(ptr::null());
let handle = {
let shorter_heap = Heap::new(ptr::null());
let longer_handle = longer_heap.wrap_handle(ptr::null());
let shorter_handle = shorter_heap.wrap_handle(ptr::null());
// longer_handle // ok to return
// shorter_handle // error: `shorter_heap` does not live long enough
};
}
寿命标记
有 3 个生命周期标记。我不会尝试在这里复制相当不错但密集的文档,但也可以指出密集的文档维基百科页面,这可能会带来一些小帮助。我按照您最有可能使用它们的顺序列出了它们:
- ContravariantLifetime
- InvariantLifetime
- CovariantLifetime