所以我试图测试我是否理解生命周期,并想创建一个在编译时失败的场景。我想出的代码如下:
#[test]
fn lifetime() {
struct Identity<'a> {
first_name: &'a str
}
let name: Identity;
{
let first: &str = "hello";
name = Identity {
first_name: first
};
}
println!("{}", name.first_name);
}
Run Code Online (Sandbox Code Playgroud)
推理是 的实例Identity应该与引用的一样长first_name。
let first: &str = "hello"然后在我使用较小范围创建的代码中,将其设置为let name: Identity;,然后在first应该超出范围之后,我尝试打印name.first_name. 我原以为这不会编译,但它编译得很好。
我对生命周期如何工作以及为什么要编译的理解中缺少什么?
#编辑
更新代码以使其编译失败:
let string = String::from("hello");
let first: &str = string.as_str();
Run Code Online (Sandbox Code Playgroud)
仍然好奇为什么原始代码有效。
因为你搬进first了name. first引用'static数据(在整个程序中存在的特殊生命周期),在本例中是一个永远不会超出范围的文字字符串。
为了使您的测试无法编译,请尝试引用超出范围的数据:
#[test]
fn lifetime() {
struct Identity<'a> {
first_name: &'a str
}
let name: Identity;
{
let first: String = String::from("hello");
name = Identity {
first_name: &first,
};
// `first` will go out of scope here and any references to it
// (like `&first` within `name`) will become invalid.
}
// `first` has been dropped so you can't reference it anymore here:
println!("{}", name.first_name);
}
Run Code Online (Sandbox Code Playgroud)