gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 11:46:47 25 4
gpt4 key购买 nike

Rust具有与非词汇生存期相关的RFC,该has been approved将在该语言中长期实现。 Recently,Rust对这个功能的支持有了很大的改善,并且被认为是完整的。

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

最佳答案

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

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从未使用过!问题在于 scoresscore的借用是 lexical-一直持续到包含它的代码块的末尾:
fn main() {
let mut scores = vec![1, 2, 3]; //
let score = &scores[0]; //
scores.push(4); //
// <-- score stops borrowing here
}
非词汇生存期可以通过增强编译器以了解这一详细程度来解决此问题。现在,编译器可以更准确地判断何时需要借用,并且此代码将进行编译。
非词汇生命周期的一个奇妙之处在于,一旦启用,就没人会考虑它们了。它会简单地变成“Rust做什么”,并且(希望)一切正常。
为什么要允许词汇生命周期?
Rust旨在仅允许编译已知安全的程序。但是, it is impossible完全只允许安全程序,而拒绝不安全程序。为此,Rust保守地说犯了错误:拒绝了某些安全程序。词汇生命周期就是一个例子。
词法生存期在编译器中更容易实现,因为对块的了解是“琐碎的”,而对数据流的了解则很少。编译器需要为 rewritten to introduce and make use of a "mid-level intermediate representation" (MIR)。然后,必须重写借位检查器(也称为“借款人”)以使用MIR而不是抽象语法树(AST)。然后,必须完善借阅检查器的规则以更细化。
词法生存期并不总是会妨碍程序员,而且有很多方法可以解决词法生存期,即使它们很烦人。在许多情况下,这涉及添加额外的花括号或 bool 值。这使得Rust 1.0得以发布,并且在实现非词性生存期之前已经有用了很多年。
有趣的是,由于词汇的生命周期,某些良好的模式得以发展。我的主要示例是 the entry pattern。此代码在非词法生存期之前会失败,并使用以下代码进行编译:
fn example(mut map: HashMap<i32, i32>, key: i32) {
match map.get_mut(&key) {
Some(value) => *value += 1,
None => {
map.insert(key, 1);
}
}
}
但是,此代码效率不高,因为它两次计算 key 的哈希值。由于词法生存期而创建的解决方案更短,更有效:
fn example(mut map: HashMap<i32, i32>, key: i32) {
*map.entry(key).or_insert(0) += 1;
}
“非词汇的生命周期”这个名字对我来说听起来不正确
值的生命周期是该值停留在特定内存地址上的时间跨度(有关详细说明,请参见 Why can't I store a value and a reference to that value in the same struct?)。称为非词汇生存期的功能不会更改任何值的生存期,因此它不能使生存期成为非词汇生存期。它只会使对这些值的借用的跟踪和检查更加精确。
该功能更准确的名称可能是“非词汇借用”。一些编译器开发人员引用了基础的“基于MIR的rowck”。
从本质上讲,非词汇生存期从来都不打算成为“面向用户”的功能。由于我们在缺席的情况下剪纸少,因此它们在我们的脑海中变得越来越大。他们的名字主要用于内部开发目的,而将其更改为用于营销目的从来都不是优先事项。
是的,但是我该如何使用呢?
在Rust 1.31(于2018-12-06发布)中,您需要在Cargo.toml中选择加入Rust 2018版本:
[package]
name = "foo"
version = "0.0.1"
authors = ["An Devloper <an.devloper@example.com>"]
edition = "2018"
从Rust 1.36开始,Rust 2015版本还启用了非词汇生存期。
当前非词汇生存期的实现方式是“迁移模式”。如果NLL借阅检查器通过,则编译将继续。如果不是,则调用先前的借阅检查器。如果旧的借阅检查器允许该代码,则会显示警告,通知您您的代码可能会在Rust的 future 版本中中断,应进行更新。
在每晚版本的Rust中,您可以通过功能标志选择加入强制性破损:
#![feature(nll)]
您甚至可以使用编译器标记 -Z polonius选择加入NLL的实验版本。
非词汇生命周期解决的实际问题的样本
  • 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?
  • Collaterally moved error when deconstructing a Box of pairs
  • 关于rust - 什么是非词汇生命周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66073264/

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