Rust基于位置的生命周期语法

新增加的~


Rust 新的基于位置的生命周期语法


前几天,Niko(也就是Rust的编译器和语言两个团队的领导)发了一篇博客,提出了一种基于位置的生命周期语法标记。这篇博客主要讲的是对Rust编译器中借用检查器的一些改进。

开篇提到了Rust的核心设计精神:修改与共享互斥。简单说,就是当你通过一个变量X去修改一个值的时候,你不能同时通过变量Y去读它。这是Rust内存安全的保证。

第一步改进:通过POLONIUS这样一个新的计算机算法,用一种新的方式来解决借用检查,特别是解决条件返回引用(conditional return reference)的问题。以下面的代码为例:

1
2
3
4
5
6
if let Some(v) = map.get(key) {
v
} else {
map.insert(key, value);
map.get(key).unwrap()
}

这里对哈希map做了一个可变借用,但在这个作用域里,它就无法再对这个map做一些可变借用了。这是受限于当前借用检查器的限制。但实际上这个例子的代码是完全没有问题的,因为当它为None的时候,不会对这个map做修改。这个经典的case是通过新的借用检查器来解决的。

第二步改进:提出了一种新的基于位置的生命周期语法标记。它在生命周期标记的时候,可以直接指定它来自哪个变量或者哪个变量字段。例如:

  • 'x 表示借用自变量x
  • 'x.y 表示借用自变量x的字段y
  • 'x.y|z 表示借用自变量x的字段y或变量z

实际代码示例:

1
2
fn example(name: &str) -> &'name str { ... }
fn get_model(&'self.model self) -> &str { ... }

这里的'name表示这个引用借用自name变量,'self.model表示借用自self的model字段。这比之前的ABC这种标记方式更容易理解。

这种基于位置的生命周期标记也能简化第一步中提到的case。我们可以直接对返回的引用标记它借用自map就行了,无需额外的生命周期标记,看起来非常简洁易懂。

第三步:更细腻的控制。以下面的代码为例:

1
2
3
4
5
6
7
8
9
10
11
impl Widget {
fn increment_counter(&mut self) {
self.count += 1;
}

fn render(&self) {
let cf = &self.widgets;
self.increment_counter();
// ...
}
}

这个代码在当前的Rust编译器中是编译不过的,因为它对cf(self.widgets)做了一个不可变的借用,但又调用了increment_counter方法,这个方法对self做了一个可变借用。当前的Rust编译器无法知道increment_counter是否会修改self的其他字段(比如widgets字段)。

引入新的基于位置的语法标记后,我们可以修改increment_counter方法,表示它只修改self的count字段:

1
2
3
fn increment_counter(&mut'self.count self) {
self.count += 1;
}

这样,这段代码就能编译通过了,实现了更细粒度的控制。

第四步:解决内部引用问题。以下面的代码为例:

1
2
3
4
5
6
7
8
9
10
11
struct Message<'text, 'to> {
text: &'text str,
to: &'to str,
}

fn example(cf: &ChatFlow) -> Message<'cf.text, 'cf.to> {
Message {
text: &cf.text,
to: &cf.to,
}
}

在新的语法标记下,可以直接用'cf.text'cf.to来标记。这样,Message就不再需要任何的生命周期类型参数了。而且从本质上说,这个Message并没有从外界借用任何东西,实际上是static的。这意味着它可以在线程之间传递,大大增强了它的能力。

从这个博客来看,这个新的语法标记并不像是一个临时起意的想法,感觉是经过长时间考虑的结果。很有可能最终会落地实施,但具体时间还不清楚。




Polonius是Rust编程语言中一个新的借用检查器(borrow checker)的实现。它是为了改进Rust的借用检查系统而开发的。以下是关于Polonius的一些关键信息:

  1. 目的:Polonius旨在使Rust的借用检查更加精确和灵活,能够接受更多合法的Rust程序。

  2. 名称来源:Polonius这个名字来自于莎士比亚的戏剧《哈姆雷特》中的一个角色。

  3. 技术基础:Polonius基于数据流分析(dataflow analysis)技术,这使得它能够更精确地推断引用的生命周期。

  4. 改进:相比于Rust现有的借用检查器,Polonius能够处理一些更复杂的借用模式,特别是在处理条件返回和非词法作用域(non-lexical lifetimes)方面表现更好。

  5. 状态:截至我最后更新的信息,Polonius仍然是一个实验性的项目,尚未完全集成到Rust的主要编译器中。

  6. 潜在影响:如果完全实施,Polonius可能会允许更多之前被拒绝的Rust代码通过编译,同时仍然保持Rust的内存安全保证。

  7. 开发过程:Polonius的开发是一个渐进的过程,Rust团队一直在进行实验和改进,以确保它能够正确处理各种复杂的Rust代码模式。

Polonius代表了Rust团队在不断优化和改进语言核心机制方面的持续努力,旨在使Rust更加强大和易用,同时保持其强大的安全性保证。

文章目录