Rust 在结构中定义多个生命周期何时有用?
在Rust中,当我们希望结构包含引用时,通常会将其生命期定义为:Rust 在结构中定义多个生命周期何时有用?,rust,lifetime,Rust,Lifetime,在Rust中,当我们希望结构包含引用时,通常会将其生命期定义为: struct Foo<'a> { x: &'a i32, y: &'a i32, } struct Foo在熬夜太晚之后,我想出了一个生命周期很重要的例子。代码如下: 静态零点:i32=0; 结构Foo{ x:&'a i32, y:&'b i32, } fn获取x_或zero_ref(x:&'ai32,y:&'bi32)->&'ai32{ 如果*x>*y{ 返回x }否则{ 归零 }
struct Foo<'a> {
x: &'a i32,
y: &'a i32,
}
struct Foo在熬夜太晚之后,我想出了一个生命周期很重要的例子。代码如下:
静态零点:i32=0;
结构Foo{
x:&'a i32,
y:&'b i32,
}
fn获取x_或zero_ref(x:&'ai32,y:&'bi32)->&'ai32{
如果*x>*y{
返回x
}否则{
归零
}
}
fn main(){
设x=1;
让v;
{
设y=2;
设f=Foo{x:&x,y:&y};
v=获取x或零参考(&f.x和&f.y);
}
println!({},*v);
}
如果要将Foo
的定义更改为:
struct Foo这里是另一个简单的示例,其中struct定义必须使用两个生存期才能按预期操作。它不会将聚合拆分为具有不同生存期的字段,而是将结构嵌套到另一个结构中
struct X<'a>(&'a i32);
struct Y<'a, 'b>(&'a X<'b>);
fn main() {
let z = 100;
//taking the inner field out of a temporary
let z1 = ((Y(&X(&z))).0).0;
assert!(*z1 == z);
}
struct X);
fn main(){
设z=100;
//将内部场从临时场中移除
设z1=(Y(&X(&z)).0;
断言!(*z1==z);
}
结构Y
有两个生存期参数,一个用于其包含的字段&X
,另一个用于X
的包含字段&z
在操作((Y(&X(&z))).0.0
中,X(&z)
被创建为临时文件并被借用。它的生存期仅在此操作的范围内,在语句结束时过期。但是由于X(&z)
的生存期不同于其包含的字段&z
,因此该操作可以返回&z
,其值可以稍后在函数中访问
如果对Y
struct使用单一生存期。此操作将不起作用,因为&z
的生存期与其包含的结构X(&z)
相同,在语句末尾过期;因此,返回的&z
不再有效,以后无法访问
请参阅中的代码。我想在这里重新回答我的问题,因为它仍然在搜索结果中显示得很高,我觉得我可以更好地解释。考虑这个代码:
这是怎么回事
f.x
的寿命要求至少足够大,以涵盖x
的范围,直到println代码>语句(因为它是用&x
初始化的,然后分配给v
)
Foo
的定义规定f.x
和f.y
使用相同的通用生存期'a
,因此f.y
的生存期必须至少与f.x
一样大
但是,这不起作用,因为我们将&y
分配给f.y
,并且y
在println之前超出范围代码>。错误李>
这里的解决方案是允许Foo
为f.x
和f.y
使用单独的生存期,我们使用多个通用生存期参数:
structfoo{
x:&'a i32,
y:&'b i32,
}
现在,f.x
和f.y
的生命周期没有联系在一起。编译器仍将使用有效的生存期,直到println代码>用于f.x
的语句。但是不再要求f.y
使用相同的生存期,因此编译器可以自由地为f.y
选择较小的生存期,例如仅对y
范围有效的生存期!我写了差不多相同的东西,15分钟前停电了。我正要把它寄出去。是的,我能想到的唯一一种情况是,当您希望能够获取一个聚合值并在使用它之后分割它的一部分,而不会丢失生存期信息。考虑建立一组值(可能涉及生命周期),使用它,然后恢复原始值。当然可以省略get_x_或_zero_ref中的'b',因为它是默认生命周期省略规则所隐含的。说函数“需要”其参数具有不同的生命周期是没有意义的。生命周期参数的用途是防止函数或结构将这些参数统一到单个(推断的)生命周期中,因此借用检查器可以区分它们。如果表达式X(&z)
提升到其自身变量中,则可以删除Y的额外生命周期。i、 e.设x=x(&z)
。是否有另一种方法强制需要额外的寿命参数?我目前正在试图理解为什么函数可能需要大于1个生存期参数。@StevenShaw是的。单独的变量x将把x(&z)提升到与z相同的作用域级别,而不是z的构造函数中的临时变量。另一方面,我的回答中的情况不是一个概念游戏,而是发生在我的实际项目中。我只是把它简化成给定的代码。对于函数,更常见的是有多个生存期参数。例如,您有两个输入借用,但返回值的生存期仅依赖于其中一个输入的生存期。谢谢,我想这可能是因为我只能在更广泛的上下文中看到它。我已经尽力想出了一个小例子,它要求函数上有多个生存期参数。例如,接受的答案可以简单地删除函数的第二个参数。如果在main
中删除不必要的作用域,它甚至可以删除结构的第二个参数。我已经收起了你的漂亮短语“概念游戏”,并将你的书添加到我的愿望列表中。@StevenShaw能够删除第二个输入的生存期参数(同时保留第一个)已经意味着它们有两个不同的生存期参数。只是根据“终身省略”规则,一个人被省略了。其次,t中main()
中v
的内部范围
struct X<'a>(&'a i32);
struct Y<'a, 'b>(&'a X<'b>);
fn main() {
let z = 100;
//taking the inner field out of a temporary
let z1 = ((Y(&X(&z))).0).0;
assert!(*z1 == z);
}
struct Foo<'a> {
x: &'a i32,
y: &'a i32,
}
fn main() {
let x = 1;
let v;
{
let y = 2;
let f = Foo { x: &x, y: &y };
v = f.x;
}
println!("{}", *v);
}
error[E0597]: `y` does not live long enough
--> src/main.rs:11:33
|
11 | let f = Foo { x: &x, y: &y };
| ^^ borrowed value does not live long enough
12 | v = f.x;
13 | }
| - `y` dropped here while still borrowed
14 | println!("{}", *v);
| -- borrow later used here
struct Foo<'a, 'b> {
x: &'a i32,
y: &'b i32,
}