gpt4 book ai didi

rust - 什么是非词汇生命周期?

转载 作者:行者123 更新时间:2023-11-29 08:31:14 25 4
gpt4 key购买 nike

锈迹与非词汇寿命有关,RFC在语言中长期存在。has been approved,Rust对这个特性的支持已经改进了很多,并且被认为是完整的。
我的问题是:什么是非词汇生命?

最佳答案

通过理解AA>生命是什么,最容易理解什么是非词汇生命。在存在非词汇生命周期之前的锈迹版本中,此代码将失败:

fn main() {
let mut scores = vec![1, 2, 3];
let score = &scores[0];
scores.push(4);
}

Rust编译器发现 scoresscore变量借用,因此它不允许 scores的进一步变异:
error[E0502]: cannot borrow `scores` as mutable because it is also borrowed as immutable
--> src/main.rs:4:5
|
3 | let score = &scores[0];
| ------ immutable borrow occurs here
4 | scores.push(4);
| ^^^^^^ mutable borrow occurs here
5 | }
| - immutable borrow ends here

然而,一个人可以很容易地看到这个例子过于保守: score从不被使用!问题是, scores借的 scorelexical-它一直持续到包含它的块的末端:
fn main() {
let mut scores = vec![1, 2, 3]; //
let score = &scores[0]; //
scores.push(4); //
// <-- score stops borrowing here
}

非词汇生命周期通过增强编译器来理解这一层次的细节来解决这个问题。编译器现在可以更准确地判断何时需要借阅,并且此代码将被编译。
关于非词汇生命周期的一个奇妙之处是,一旦启用,就没有人会想到它们。它只会变成“铁锈的作用”,一切都会(希望)正常运转。
为什么会有词汇生命期?
Rust只允许编译已知的安全程序。但是, lexical只允许安全程序,拒绝不安全程序。为此,Rust在保守方面犯了错误:一些安全程序被拒绝。词汇寿命就是这样的一个例子。
在编译器中,词汇生命周期更容易实现,因为块的知识是“琐碎的”,而对数据流的了解则更少。编译器需要 it is impossible。然后,借阅检查器(也称为“借阅”)必须重写为使用MIR而不是抽象语法树(AST)。然后,必须对借阅检查器的规则进行改进,使其更精细。
词汇生命周期并不总是妨碍程序员的工作,当他们工作时,有很多方法可以绕过词汇生活,即使它们很烦人。在许多情况下,这需要添加额外的花括号或布尔值。这允许锈蚀1在非词汇生命期之前被使用并在许多年之前被使用。
有趣的是,某些良好的模式是由于词汇寿命而发展的。对我来说,最好的例子是 rewritten to introduce and make use of a "mid-level intermediate representation" (MIR)。此代码在非词汇生命周期之前失败,并与之编译:
fn example(mut map: HashMap<i32, i32>, key: i32) {
match map.get_mut(&key) {
Some(value) => *value += 1,
None => {
map.insert(key, 1);
}
}
}

但是,这段代码效率低下,因为它计算了两次密钥的散列。由于词汇生命周期而产生的解决方案较短且效率更高:
fn example(mut map: HashMap<i32, i32>, key: i32) {
*map.entry(key).or_insert(0) += 1;
}

“非词汇生命”这个名字对我来说并不正确。
值的生存期是值停留在特定内存地址的时间跨度(有关详细说明,请参见 the entry pattern)。被称为非词汇生命周期的特征不会改变任何值的生命周期,因此它不能使生命非词汇化。它只会使对这些价值的借款的跟踪和检查更加精确。
一个更准确的名称是“非词汇借用”。一些编译器开发人员提到了底层的“基于MIR的借阅”。
非词汇生命期本身从来不是一个“面向用户”的特征。它们在我们的脑海里变得很大,主要是因为我们从它们的缺席中得到了一些小的剪纸。他们的名字主要是为了内部发展的目的,而为了营销的目的而改变它从来不是一个优先事项。
是的,但是我该怎么用呢?
在Rust 1.31(于2018-12-06发布)中,您需要选择在货物中使用Rust 2018版本。toml:
[package]
name = "foo"
version = "0.0.1"
authors = ["An Devloper <an.devloper@example.com>"]
edition = "2018"

锈1.36,锈2015版也使非词汇寿命。
当前非词汇生命周期的实现是一种“迁移模式”。如果NLL借阅检查器通过,编译将继续。如果没有,则调用上一个借阅检查器。如果旧的借阅检查器允许使用该代码,则会打印一条警告,通知您您的代码很可能会在将来的版本中生锈并应进行更新。
在夜间版本的Rust中,您可以通过一个功能标志选择强制破坏:
#![feature(nll)]

通过使用编译器标志 -Z polonius,您甚至可以选择使用NLL的实验版本。
非词汇生命周期解决实际问题的样本
Why can't I store a value and a reference to that value in the same struct?
Returning a reference from a HashMap or Vec causes a borrow to last beyond the scope it's in?
Why does HashMap::get_mut() take ownership of the map for the rest of the scope?
Cannot borrow as immutable because it is also borrowed as mutable in function arguments
How to update-or-insert on a Vec?
Is there a way to release a binding before it goes out of scope?
Cannot obtain a mutable reference when iterating a recursive structure: cannot borrow as mutable more than once at a time
When returning the outcome of consuming a StdinLock, why was the borrow to stdin retained?

关于rust - 什么是非词汇生命周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57189167/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com