mirror of
https://github.com/rust-lang-cn/book-cn.git
synced 2025-01-22 23:10:20 +08:00
修正一些小的符号与语法错误 ch10-03-lifetime-syntax.md (#123)
Co-authored-by: YangQi <2419731931@qq.com>
This commit is contained in:
parent
87ff95b77e
commit
210ac463ee
@ -22,7 +22,7 @@
|
||||
|
||||
- [认识所有权](ch04-00-understanding-ownership.md)
|
||||
- [什么是所有权?](ch04-01-what-is-ownership.md)
|
||||
- [引用和借用](ch04-02-references-and-borrowing.md)
|
||||
- [引用与借用](ch04-02-references-and-borrowing.md)
|
||||
- [切片 slice](ch04-03-slices.md)
|
||||
|
||||
- [使用结构体组织关联数据](ch05-00-structs.md)
|
||||
|
@ -1,12 +1,12 @@
|
||||
## 生命周期与引用有效性
|
||||
|
||||
当在第 4 章讨论 [“引用和借用”][references-and-borrowing] 部分时,我们遗漏了一个重要的细节:Rust 中的每一个引用都有其 **生命周期**(*lifetime*),也就是引用保持有效的作用域。大部分时候生命周期是隐含并可以推断的,正如大部分时候类型也是可以推断的一样。类似于当因为有多种可能类型的时候必须注明类型,也会出现引用的生命周期以一些不同方式相关联的情况,所以 Rust 需要我们使用泛型生命周期参数来注明他们的关系,这样就能确保运行时实际使用的引用绝对是有效的。
|
||||
当在第 4 章讨论 [“引用与借用”][references-and-borrowing] 部分时,我们遗漏了一个重要的细节:Rust 中的每一个引用都有其 **生命周期**(*lifetime*),也就是引用保持有效的作用域。大部分时候生命周期是隐含并可以推断的,正如大部分时候类型也是可以推断的一样。类似于当因为有多种可能类型的时候必须注明类型,也会出现引用的生命周期以一些不同方式相关联的情况,所以 Rust 需要我们使用泛型生命周期参数来注明他们的关系,这样就能确保运行时实际使用的引用绝对是有效的。
|
||||
|
||||
生命周期的概念从某种程度上说不同于其他语言中类似的工具,毫无疑问这是 Rust 最与众不同的功能。虽然本章不可能涉及到它全部的内容,我们会讲到一些通常你可能会遇到的生命周期语法以便你熟悉这个概念。
|
||||
|
||||
### 生命周期避免了悬垂引用
|
||||
|
||||
生命周期的主要目标是避免悬垂引用,它会导致程序引用了非预期引用的数据。考虑一下示例 10-17 中的程序,它有一个外部作用域和一个内部作用域.
|
||||
生命周期的主要目标是避免悬垂引用,它会导致程序引用了非预期引用的数据。考虑一下示例 10-17 中的程序,它有一个外部作用域和一个内部作用域。
|
||||
|
||||
```rust,ignore,does_not_compile
|
||||
{
|
||||
@ -44,7 +44,7 @@ error[E0597]: `x` does not live long enough
|
||||
|
||||
#### 借用检查器
|
||||
|
||||
Rust 编译器有一个 **借用检查器**(*borrow checker*),它比较作用域来确保所有的借用都是有效的。示例 10-18 展示了与示例 10-17 相同的例子不过带有变量生命周期的注释:
|
||||
Rust 编译器有一个 **借用检查器**(*borrow checker*),它比较作用域来确保所有的借用都是有效的。示例 10-18 展示了与示例 10-17 相同的例子,不过带有变量生命周期的注释:
|
||||
|
||||
```rust,ignore,does_not_compile
|
||||
{
|
||||
@ -366,7 +366,7 @@ fn first_word<'a>(s: &'a str) -> &'a str {
|
||||
|
||||
第二条规则是如果只有一个输入生命周期参数,那么它被赋予所有输出生命周期参数:`fn foo<'a>(x: &'a i32) -> &'a i32`。
|
||||
|
||||
第三条规则是如果方法有多个输入生命周期参数并且其中一个参数是 `&self` 或 `&mut self`,说明是个对象的方法(method)(译者注: 这里涉及 Rust 的面向对象参见 17 章), 那么所有输出生命周期参数被赋予 `self` 的生命周期。第三条规则使得方法更容易读写,因为只需更少的符号。
|
||||
第三条规则是如果方法有多个输入生命周期参数并且其中一个参数是 `&self` 或 `&mut self`,说明是个对象的方法(method)(译者注: 这里涉及 Rust 的面向对象,参见第 17 章), 那么所有输出生命周期参数被赋予 `self` 的生命周期。第三条规则使得方法更容易读写,因为只需更少的符号。
|
||||
|
||||
假设我们自己就是编译器。并应用这些规则来计算示例 10-26 中 `first_word` 函数签名中的引用的生命周期。开始时签名中的引用并没有关联任何生命周期:
|
||||
|
||||
@ -400,7 +400,7 @@ fn longest(x: &str, y: &str) -> &str {
|
||||
fn longest<'a, 'b>(x: &'a str, y: &'b str) -> &str {
|
||||
```
|
||||
|
||||
再来应用第二条规则,因为函数存在多个输入生命周期,它并不适用于这种情况。再来看第三条规则,它同样也不适用,这是因为没有 `self` 参数。应用了三个规则之后编译器还没有计算出返回值类型的生命周期。这就是为什么在编译示例 10-21 的代码时会出现错误的原因:编译器使用所有已知的生命周期省略规则,仍不能计算出签名中所有引用的生命周期。
|
||||
再来应用第二条规则,因为函数存在多个输入生命周期,它并不适用于这种情况。再来看第三条规则,它同样也不适用,这是因为没有 `self` 参数。应用了三个规则之后编译器还没有计算出返回值类型的生命周期。这就是我们在尝试编译示例 10-21 中的代码时出现错误的原因:编译器使用所有已知的生命周期省略规则,仍不能计算出签名中所有引用的生命周期。
|
||||
|
||||
因为第三条规则真正能够适用的就只有方法签名,现在就让我们看看那种情况中的生命周期,并看看为什么这条规则意味着我们经常不需要在方法签名中标注生命周期。
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user