我正在阅读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中,当我们想要一个包含引用的结构时,我们通常会定义它们的生命周期:
struct Foo<'a> {
x: &'a i32,
y: &'a i32,
}
Run Code Online (Sandbox Code Playgroud)
但是也可以为同一结构中的不同引用定义多个生命周期:
struct Foo<'a, 'b> {
x: &'a i32,
y: &'b i32,
}
Run Code Online (Sandbox Code Playgroud)
什么时候这样做有用?有人可以提供一些示例代码,这些代码在两个生命周期都'a没有编译但是在生命周期时编译'a并且'b(反之亦然)?
如果我有这两个功能
// implicit
fn foo(x: &i32) {
}
// explicit
fn bar<'a>(x: &'a i32) {
}
Run Code Online (Sandbox Code Playgroud)
何时会foo返回错误并bar成为正确的函数头?我很困惑为什么我会明确地声明一生:
'a读'生命'a'.从技术上讲,每个引用都有一些与之相关的生命周期,但编译器允许您在常见情况下忽略它们.
我明白一生是什么,但明确指定一生的'a 事情对我有什么影响?作为参考,我使用Rust书作为阅读材料
这个问题类似于什么时候在结构中定义多个生命周期有用?,但希望足够不同.这个问题的答案很有帮助,但侧重于一种方法的优点(对结构中的引用使用不同的生命周期),而不是缺点(如果有的话).像这样的问题,正在寻找关于如何在创建结构时选择生命周期的指导.
将此称为捆绑在一起的版本,因为x和y需要具有相同的生命周期:
struct Foo<'a> {
x: &'a i32,
y: &'a i32,
}
Run Code Online (Sandbox Code Playgroud)
并将其称为松散版本,因为生命周期可能会有所不同:
struct Foo<'a, 'b> {
x: &'a i32,
y: &'b i32,
}
Run Code Online (Sandbox Code Playgroud)
引用问题的答案给出了一个明确的案例,其中客户端代码可以在松散版本的情况下编译/运行,但是对于捆绑在一起的版本将会失败.是不是所有适用于捆绑版本的客户端代码也适用于松散版本并且保证安全(即安全)?正面不是真的.从结构设计者的角度来看,松散版本显然更加灵活.鉴于它是一个好的/可接受的答案,指导可能是 - 当在结构中使用引用时总是给它们不同的生命周期.
这个建议的缺点是什么,忽略了额外的打字?例如,在结构中要求引用具有相同的生命周期是否有益处?