Rust 什么是非词汇生命期?

Rust 什么是非词汇生命期?,rust,terminology,lifetime,lifetime-scoping,Rust,Terminology,Lifetime,Lifetime Scoping,Rust与非词汇生命周期相关,而非词汇生命周期将在语言中长期实现,Rust对该功能的支持有了很大的改进,被认为是完整的 我的问题是:什么是非词汇生命期?通过了解生命期是什么,最容易理解什么是非词汇生命期。在非词法生存期出现之前的Rust版本中,此代码将失败: fn main() { let mut scores = vec![1, 2, 3]; let score = &scores[0]; scores.push(4); } Rust编译器发现score是由s

Rust与非词汇生命周期相关,而非词汇生命周期将在语言中长期实现,Rust对该功能的支持有了很大的改进,被认为是完整的


我的问题是:什么是非词汇生命期?

通过了解生命期是什么,最容易理解什么是非词汇生命期。在非词法生存期出现之前的Rust版本中,此代码将失败:

fn main() {
    let mut scores = vec![1, 2, 3];
    let score = &scores[0];
    scores.push(4);
}
Rust编译器发现
score
是由
score
变量借用的,因此它不允许
scores
进一步变异:

error[E0502]:无法将'scores'作为可变项借用,因为它也是作为不可变项借用的
-->src/main.rs:4:5
|
3 |让分数=&分数[0];
|----此处发生不可变借用
4分。推(4);
|^^^^^^^此处发生可变借用
5 | }
|-不可变的借阅到此结束
然而,人们可以很容易地看到这个例子过于保守:
分数
从未使用过的!问题在于,通过
score
借用
scores
是-它持续到包含它的块的末尾:

fn main() {
    let mut scores = vec![1, 2, 3]; //
    let score = &scores[0];         //
    scores.push(4);                 //
                                    // <-- score stops borrowing here
}
但是,这段代码效率很低,因为它会计算两次密钥的哈希值。由于词法生命周期而创建的解决方案更短、效率更高:

fn example(mut map: HashMap<i32, i32>, key: i32) {
    *map.entry(key).or_insert(0) += 1;
}
您甚至可以使用编译器标志
-Z polonius
选择NLL的实验版本

由非词汇生命周期解决的实际问题示例

我认为值得强调的是,也许与直觉相反,非词汇生命周期与变量的生命周期无关,而是与借词的生命周期有关。或者,也就是说,非词汇生存期是关于将变量的生存期与借词的生存期去相关。。。除非我错了?(但我不认为在执行析构函数时NLL会发生变化)“有趣的是,某些好的模式是由于词法寿命而发展起来的”-我想,NLL的存在可能会使未来的好模式更难识别?@eggyal这当然是可能的。在一组约束条件下进行设计(即使是任意的!)可以产生新的、有趣的设计。如果没有这些限制,我们可能会依赖现有的知识和模式,永远不会学习或探索新的东西。这就是说,可能有人会认为“哦,哈希值被计算了两次,我可以解决这个问题”,然后会创建API,但用户可能更难首先找到API。我希望像这样的工具能够帮助这些人。考虑到它特别缩短了绑定的生命周期估计值,也许命名上更好的改进是,子词汇生命周期。此外,如上所述,地址粘性与生存期没有任何关系,因为附加到向量(
push
)可以强制重新分配,从而在不丢失其绑定引用的情况下更改其地址。对于这个新手来说,似乎整个生命周期系统都与绑定有关:所有者、借贷者和观察者(也称为共享)。想想看,Rust中的观察者模式可能过于简单化了。
fn example(mut map: HashMap<i32, i32>, key: i32) {
    *map.entry(key).or_insert(0) += 1;
}
[package]
name = "foo"
version = "0.0.1"
authors = ["An Devloper <an.devloper@example.com>"]
edition = "2018"
#![feature(nll)]