我有一个值,我想在我自己的类型中存储该值以及对该值内部内容的引用:
struct Thing {
count: u32,
}
struct Combined<'a>(Thing, &'a u32);
fn make_combined<'a>() -> Combined<'a> {
let thing = Thing { count: 42 };
Combined(thing, &thing.count)
}
Run Code Online (Sandbox Code Playgroud)
有时候,我有一个值,我想在同一个结构中存储该值和对该值的引用:
struct Combined<'a>(Thing, &'a Thing);
fn make_combined<'a>() -> Combined<'a> {
let thing = Thing::new();
Combined(thing, &thing)
}
Run Code Online (Sandbox Code Playgroud)
有时,我甚至没有参考该值,我得到同样的错误:
struct Combined<'a>(Parent, Child<'a>);
fn make_combined<'a>() -> Combined<'a> {
let parent = Parent::new();
let child = parent.child();
Combined(parent, child)
}
Run Code Online (Sandbox Code Playgroud)
在每种情况下,我都会收到一个错误,即其中一个值"活不够长".这个错误是什么意思?
我正在阅读Rust书的生命周章,我在这个例子中看到了命名/显式生命周期:
struct Foo<'a> {
x: &'a i32,
}
fn main() {
let x; // -+ x goes into scope
// |
{ // |
let y = &5; // ---+ y goes into scope
let f = Foo { x: y }; // ---+ f goes into scope
x = &f.x; // | | error here
} // ---+ f and y go out of scope
// |
println!("{}", x); // |
} // -+ x goes out …Run Code Online (Sandbox Code Playgroud) 我正试着在Rust中度过生命,并问自己,他们是否"只是"一种安全措施(以及在错误的情况下沟通如何确保安全性的方式)或者是否存在不同选择的情况生命周期实际上改变了程序的运行方式,即生命周期是否与编译的程序产生语义差异.
并以"寿命"我指的是所有讨厌的小'a,'b,'static标志我们包括使借检查开心.当然,写作
{
let foo = File::open("foo.txt")?;
}
foo.write_all(b"bar");
Run Code Online (Sandbox Code Playgroud)
代替
let foo = File::open("foo.txt")?;
foo.write_all(b"bar");
Run Code Online (Sandbox Code Playgroud)
将在写入发生之前关闭文件描述符,即使我们之后可以访问foo,但是这种范围和析构函数调用也会在C++中发生.
我想管理另一个对象中的对象集合,但我无法预测该集合中元素的生命周期。
我在Syntax of Rust 生命周期说明符中找到了这个例子,它演示了我不能做的事情:
struct User<'a> {
name: &'a str,
}
// ... impls omitted
struct ChatRoom<'a> {
name: &'a str,
users: HashMap<&'a str, User<'a>>,
}
Run Code Online (Sandbox Code Playgroud)
ChatRoom持有Users的地图。每个User都是一个副本,尽管其中的名称User是共享引用。TheUser和 theChatRoom具有明确的生命周期,因此当它们加入时,编译器强制Users 必须比ChatRoom它们进入的寿命更长。
但是如果 myUser是在 之后创建的ChatRoom呢?我不能使用生命周期,因为编译器会抱怨。如果我删除User之前的ChatRoom? 我也不能那样做。
可能在它之后创建或在它之前销毁的ChatRoomhold Users怎么可能?我模糊地怀疑可以用盒子来实现这一点,但 Rust 的盒子文档很差,所以我不确定。