0
 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链接code snippet 1

以上内容code snippnet 1Rust for Rustacean Ch1 清单 1-11 不同,其中我使用'a替换两个生命周期'a'b,并且此代码无法编译,而我无法说出原因:(

我可以分析一些简单的代码,例如以下代码(来自 Programming Rust Vers 2 page 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链接code snippet 2

我分别表示xyr、和'x的 生命周期:'y'r

'X 'y '
线路:从 8 到 18 线路:从 11 到 16 线路:从 9 到 17

当在线实例化s13,我们正在要求'x:'a ('x outlives 'a) 'y:'a,而当分配r = s.x发生在队列中时14,我们正在要求'a:'r。然而,这是不可能的,因为'y:'a冲突'a:'r(见上表,'y比 短'r),因此 rustc 无法找到'a满足这些冲突条件的通用生命周期的确定性生命周期。

更新:我期待 code snippet 1与上述类似的分析过程,或者遇到生命周期问题时的一般推理方法:)

我已经阅读了这篇文章,了解了一些基本概念variance,例如covariance invariancecontravariance。而且我有点认为我的问题与此有关,但不知道如何使用它来分析code snippet 1

顺便说一句,我仍然想知道掌握lifetimerust 的正确位置是什么。如果你知道,请告诉我:),我很感激。

如果您发现我的问题不正常,请随时指出:)

4

1 回答 1

2

我读过这篇文章,了解了一些关于方差的基本概念,例如协方差不变性和逆变性。我有点认为我的问题与此有关,但不知道如何使用它来分析代码片段 1。

您走在正确的轨道上,差异确实在于终生差异。Rust Reference 10.5 Subtyping and Variance中有一张我认为很有帮助的表格:

类型 差异'a 差异T
&'a T 协变 协变
&'a mut T 协变 不变的

在您的第二个片段中,您的引用是不可变的,这意味着可以根据需要缩短与它们相关的生命周期。对变量的引用y不能延长其生命周期,因此x必须缩短对变量的引用。因此,绑定到的引用与r的生命周期相关联y,因此当您尝试在超出范围r后使用时会出现错误。y

然而,在第一个片段中,您有一个对 a 的可变引用&'a str。如果您查看上表,您会发现可变引用所引用的类型是不变的,并且由于类型本身是 a &'a str,这意味着它'a是不变的。这意味着,与第二个片段不同,编译器根本不能缩短生命周期'a。因此,当您尝试使用smake aMutStr时,编译器会看到您传递的 a&'static str它不能缩短,所以'amust be 'static。但随后它会尝试协调'a也链接到s不是的变量'static,因此您会收到错误消息。

于 2022-02-06T04:45:43.137 回答