我发现PhantomData
Rust 中的概念相当混乱。我在基于 FFI 的代码中广泛使用它来限制对象的生命周期,但我仍然不确定我是否正确地执行了此操作。
这是我经常最终使用它的人为示例。例如,我不希望 的实例MyStruct
比 的实例寿命长Context
:
// FFI declarations and types
mod ffi {
use std::ffi::c_void;
pub type handle_t = *const c_void;
// ...
}
// A wrapper structure for some context created and maintained
// inside the C library
struct Context {
// ...
}
// Handle is only valid as long as the Context is alive.
// Hence, I use the PhantomData marker to constrain its lifetime.
struct MyStruct<'a> {
marker: PhantomData<&'a Context>,
handle: ffi::handle_t,
}
impl<'a> MyStruct<'a> {
fn new(context: &'a Context) -> Self {
let handle: ffi::handle_t = context.new_handle();
MyStruct {
marker: PhantomData,
handle
}
}
}
fn main() {
// Initialize the context somewhere inside the C library
let ctx = Context::new(unsafe {ffi::create_context()});
// Create an instance of MyStruct
let my_struct = MyStruct::new(&ctx);
// ...
}
我不太明白以下内容:
marker: PhantomData
从语法上讲,这到底是什么东西?我的意思是,它看起来不像构造函数,我希望它类似于PhantomData{}
orPhantomData()
。出于生命周期跟踪的目的,是否
PhantomData
甚至关心声明中的实际类型marker
?我尝试将其更改为PhantomData<&'a usize>
,它仍然有效。在我的
MyStruct::new()
方法的声明中,如果我忘记显式指定参数的'a
生命周期context
,那么 的魔力PhantomData
就会消失,并且可以丢弃Context
beforeMyStruct
。这是相当阴险的;编译器甚至没有给出警告。那么它分配给什么生命周期marker
,为什么?与上一个问题相关;如果有多个输入引用参数可能具有不同的生命周期,如何
PhantomData
确定使用哪个生命周期?