与方差相关时如何分析泛型寿命
How to analyze generic lifetime when it is relevant to variance
0 // code snippet 1
1
2 struct MutStr<'a >{
3 s: &'a mut &'a str,
4 }
5
6 fn main() {
7 let mut s: &'static str = "hello";
8 *MutStr{
9 s: &mut s,
10 }.s = "world";
11 println!("{}", s);
12 }
Rust Playground link of code snippet 1
上面的 code snippnet 1
不同于 Rust for Rustacean Ch1 清单 1-11,其中我使用 'a
来替换两个生命周期 'a
和 'b
,而这个代码无法编译,而我也说不出原因:(
我可以分析一些简单的代码,例如以下代码(来自 Programming Rust Verson 2 第 120 页):
0 // code snippet 2
1
2 struct S<'a> {
3 x: &'a i32,
4 y: &'a i32
5 }
6
7 fn main() {
8 let x = 10;
9 let r;
10 {
11 let y = 20;
12 {
13 let s = S {x: &x, y: &y};
14 r = s.x;
15 }
16 }
17 println!("{}", r);
18 }
Rust Playground link of code snippet 2
我分别用 'x
、'y
和 'r
表示 x
、y
和 r
的生命周期:
'x
'y
'r
line: from 8 to 18
line: from 11 to 16
line: from 9 to 17
在 13
行中实例化 s
时,我们需要 'x:'a ('x outlives 'a)
'y:'a
,并且在 14
行中发生赋值 r = s.x
,我们需要 'a:'r
。然而,这是不可能的,因为 'y:'a
与 'a:'r
冲突(参见上面的 table,'y
比 'r
短),因此 rustc 无法找到满足这些冲突条件的通用生命周期 'a
的确定性生命周期。
更新:期待code snippet 1
的分析过程和上面类似,或者遇到生命周期问题时的通用推理方法:)
我读过 this article ,知道一些关于 variance
的基本概念,例如 covariance
invariance
和 contravariance
。我觉得我的问题与此有关,但不知道如何使用它来分析 code snippet 1
。
对了,我还在疑惑掌握lifetime
在rust中什么位置才是正确的。如果你知道,请告诉我:),我很感激。
If you find my question irregular, feel free to point it out:)
I have read this article, knowing some basic concepts about variance, such as covariance invariance and contravariance. And I kind of think my question relate to that, but don't know how to use that to analyze code snippet 1.
你走在正确的轨道上,不同之处在于生命周期的差异。 Rust Reference 10.5 Subtyping and Variance里面有个table我觉得有帮助:
Type
Variance in 'a
Variance in T
&'a T
covariant
covariant
&'a mut T
covariant
invariant
在您的第二个代码段中,您的引用是 immutable,这意味着可以根据需要缩短与它们关联的生命周期。对变量 y
的引用不能延长其生命周期,因此必须缩短对 x
的引用。因此,绑定到 r
的引用与 y
的生命周期相关联,因此当您在 y
超出范围后尝试使用 r
时会出现错误。
然而,在第一个片段中,您有一个 mutable 引用 &'a str
。如果您查看上面的 table,您会发现 mutable 引用所引用的类型是不变的,并且由于类型本身是 &'a str
,这意味着 'a
是不变的。这意味着,与第二个片段不同,编译器 根本无法 缩短 'a
的生命周期。因此,当您尝试使用 s
生成 MutStr
时,编译器会发现您传递的是无法缩短的 &'static str
,因此 'a
必须是 'static
.但随后它试图调和 'a
也链接到变量 s
而不是 'static
,所以你得到错误。
0 // code snippet 1
1
2 struct MutStr<'a >{
3 s: &'a mut &'a str,
4 }
5
6 fn main() {
7 let mut s: &'static str = "hello";
8 *MutStr{
9 s: &mut s,
10 }.s = "world";
11 println!("{}", s);
12 }
Rust Playground link of
code snippet 1
上面的 code snippnet 1
不同于 Rust for Rustacean Ch1 清单 1-11,其中我使用 'a
来替换两个生命周期 'a
和 'b
,而这个代码无法编译,而我也说不出原因:(
我可以分析一些简单的代码,例如以下代码(来自 Programming Rust Verson 2 第 120 页):
0 // code snippet 2
1
2 struct S<'a> {
3 x: &'a i32,
4 y: &'a i32
5 }
6
7 fn main() {
8 let x = 10;
9 let r;
10 {
11 let y = 20;
12 {
13 let s = S {x: &x, y: &y};
14 r = s.x;
15 }
16 }
17 println!("{}", r);
18 }
Rust Playground link of
code snippet 2
我分别用 'x
、'y
和 'r
表示 x
、y
和 r
的生命周期:
'x | 'y | 'r |
---|---|---|
line: from 8 to 18 | line: from 11 to 16 | line: from 9 to 17 |
在 13
行中实例化 s
时,我们需要 'x:'a ('x outlives 'a)
'y:'a
,并且在 14
行中发生赋值 r = s.x
,我们需要 'a:'r
。然而,这是不可能的,因为 'y:'a
与 'a:'r
冲突(参见上面的 table,'y
比 'r
短),因此 rustc 无法找到满足这些冲突条件的通用生命周期 'a
的确定性生命周期。
更新:期待code snippet 1
的分析过程和上面类似,或者遇到生命周期问题时的通用推理方法:)
我读过 this article ,知道一些关于 variance
的基本概念,例如 covariance
invariance
和 contravariance
。我觉得我的问题与此有关,但不知道如何使用它来分析 code snippet 1
。
对了,我还在疑惑掌握lifetime
在rust中什么位置才是正确的。如果你知道,请告诉我:),我很感激。
If you find my question irregular, feel free to point it out:)
I have read this article, knowing some basic concepts about variance, such as covariance invariance and contravariance. And I kind of think my question relate to that, but don't know how to use that to analyze code snippet 1.
你走在正确的轨道上,不同之处在于生命周期的差异。 Rust Reference 10.5 Subtyping and Variance里面有个table我觉得有帮助:
Type | Variance in 'a |
Variance in T |
---|---|---|
&'a T |
covariant | covariant |
&'a mut T |
covariant | invariant |
在您的第二个代码段中,您的引用是 immutable,这意味着可以根据需要缩短与它们关联的生命周期。对变量 y
的引用不能延长其生命周期,因此必须缩短对 x
的引用。因此,绑定到 r
的引用与 y
的生命周期相关联,因此当您在 y
超出范围后尝试使用 r
时会出现错误。
然而,在第一个片段中,您有一个 mutable 引用 &'a str
。如果您查看上面的 table,您会发现 mutable 引用所引用的类型是不变的,并且由于类型本身是 &'a str
,这意味着 'a
是不变的。这意味着,与第二个片段不同,编译器 根本无法 缩短 'a
的生命周期。因此,当您尝试使用 s
生成 MutStr
时,编译器会发现您传递的是无法缩短的 &'static str
,因此 'a
必须是 'static
.但随后它试图调和 'a
也链接到变量 s
而不是 'static
,所以你得到错误。