type
status
date
slug
summary
tags
category
icon
password
Property
Mar 24, 2023 05:13 AM
好长时间没写博客了,现在在上海开始上班,算是新的开始。
今天随便读了一下Rust死灵书,记录一下自己的领悟。
这里的问题更微妙、更有趣。我们希望 Rust 拒绝这个程序,理由如下:我们有一个存活的共享引用x
到data
的一个子集,当我们试图把data
的可变引用传给push
时。这将创建一个可变引用的别名,而这将违反引用的第二条规则。
然而,这根本不是 Rust 认为这个程序有问题的原因。Rust 不理解x
是对data
的一个子集的引用。它根本就不理解Vec
。它看到的是,x
必须在'b
范围内保持存活才能被打印;接下来,Index::index
的签名要求我们对data
的引用必须在'b
范围内存活。当我们试图调用push
时,它看到我们试图构造一个&'c mut data
。Rust 知道'c
包含在'b
中,并拒绝了我们的程序,因为&'b data
必然还存活着!
在这里我们看到,和我们真正想要保证的引用规则语义相比,生命周期系统要粗略得多。在大多数情况下,这完全没问题,因为它使我们不用花整天的时间向编译器解释我们的程序。然而,这确实意味着有部分程序对于 Rust 的真正的语义来说是完全正确的,但却被拒绝了,因为 lifetime 太傻了。
上面这一段是生命周期的一个例子,我愣是看了好长时间才懂了下面说的是什么。
简单来说上面的代码违反了Rust的一个引用规则:不可变引用可以存在多个,但是可变引用只能存在一个。
x在b区域内被创建,为一个不可变引用,但是data.push创造了一个可变引用,所以这里无法通过编译。
解决方法也很简单,把
println!("{}", x);
往上面调整一行就可以了,这样x不再使用,rust就认为x的生命周期已经结束。- 作者:sdttttt
- 链接:https://www.sdttttt.site/article/fe595d36-1f64-4644-baf7-e234e6a19c25
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。