Rom*_*nko 4 ffi rust phantom-types
我发现PhantomDataRust 中的概念非常混乱。我广泛使用它来限制基于 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);
// ...
}
Run Code Online (Sandbox Code Playgroud)
我不太明白以下内容:
这东西到底是marker: PhantomData什么,在语法上?我的意思是,它看起来不像一个构造函数,我希望它像PhantomData{}or 那样PhantomData()。
出于生命周期跟踪的目的,PhantomData甚至不关心marker?声明中的实际类型?我尝试将其更改为PhantomData<&'a usize>,它仍然有效。
在我的MyStruct::new()方法的声明中,如果我忘记明确指定参数的'a生命周期context, 的魔力就会PhantomData消失,并且可以Context在MyStruct. 这是非常阴险的;编译器甚至不发出警告。那么它分配给什么生命周期marker,为什么?
与上一个问题相关;如果存在多个生命周期可能不同的输入引用参数,如何PhantomData确定使用哪个生命周期?
这东西到底是
marker: PhantomData什么,在语法上?我的意思是,它看起来不像一个构造函数,我希望它像PhantomData{}or 那样PhantomData()。
您可以定义一个零字段结构,如下所示:
struct Foo;
Run Code Online (Sandbox Code Playgroud)
并像这样创建它的一个实例:
let foo: Foo = Foo;
Run Code Online (Sandbox Code Playgroud)
类型和值都命名为Foo。
出于生命周期跟踪的目的,
PhantomData甚至关心标记声明中的实际类型吗?我尝试将其更改为PhantomData<&'a usize>,它仍然有效。
没有什么特别之处,PhantomData只是它的类型参数未使用不是错误(请参阅源代码)。此行为通过#[lang = "phantom_data"]属性启用,该属性只是编译器中用于此目的的一个钩子。
在我的
MyStruct::new()方法的声明中,如果我忘记明确指定参数的'a生命周期context, 的魔力就会PhantomData消失,并且可以Context在MyStruct. 这是非常阴险的;编译器甚至不发出警告。那么它分配给什么生命周期marker,为什么?
PhantomData是否可以让您告诉编译器信息它无法自行推断,因为该信息是关于您没有直接使用的类型。由您来为编译器提供正确的信息。
在我的
MyStruct::new()方法的声明中,如果我忘记明确指定参数的'a生命周期context, 的魔力就会PhantomData消失,并且可以Context在MyStruct. 这是非常阴险的;编译器甚至不发出警告。那么它分配给什么生命周期marker,为什么?
我不完全确定我是否理解这个问题。PhantomData没有做任何事情-它只是一个给你以某种方式使用数据,它是由你来准确地表达信息的编译器沟通的方式。请注意,即使您错误地表达了约束,也只有在您也有unsafe代码的情况下才有可能引入内存不安全。正确表达生命周期PhantomData是围绕不安全代码创建安全抽象的一部分。
| 归档时间: |
|
| 查看次数: |
2357 次 |
| 最近记录: |