我试图理解 rust 中的 phantomData,我有一个 Foo 结构包裹着一个原始指针,我告诉编译器 Foo 不能比 'a 更长寿,所以我试图防止属性 v 的值在 Foo 之前被删除,但是我发现当 String s 可以在 f 之前删除时,它不起作用。我是不是误会了什么?
struct Foo<'a, T: 'a> { // I say that T is valid over lifetime 'a
pub v: *mut T,
_mark: PhantomData<&'a T>
}
fn main() {
let mut s = String::from("hello");
let f = Foo {
v: &mut s,
_mark: PhantomData,
};
drop(s);
drop(f);
}
我发现我什至可以在 s 被删除后使用指向 s 的指针,如下所示
let mut s = String::from("hello");
let f = Foo {
v: &mut s,
_mark: PhantomData,
};
drop(s);
let a = unsafe {&*f.v};
println!("{}", a);
从评论中,我认为混乱来自于T: 'a
和一生的推断。这的意思T: 'a https://doc.rust-lang.org/stable/rust-by-example/scope/lifetime/lifetime_bounds.html是任何生命周期参数T
只要'a
。对于一个类型T
like String
,没有生命周期参数,因此对于任何值都是如此'a
包括'static
.
大致说来,T: 'a
意味着你可以持有一个类型的值T
只要'a
。它必须拥有自己的数据(例如String
)或其包含的任何引用都必须存在足够长的时间。
因此当你初始化时f
:
let f = Foo {
v: &mut s,
_mark: PhantomData,
};
T
可以推断为String
,但任何值'a
已验证。寿命没有限制。
必须以某种方式告诉编译器初始化引用的生命周期(我们在初始化之前将其转换为无生命周期指针)Foo
) 与我们想要使用的生命周期相关Foo
。例如:
impl<'a, T: 'a> Foo<'a, T> {
// the input lifetime and the output lifetime are the same
fn new(t: &'a mut T) -> Foo<'a, T> {
Foo {
v: t,
_mark: PhantomData,
}
}
}
let f = Foo::new(&mut s);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)