【发布时间】:2019-12-03 20:43:53
【问题描述】:
我是 Rust 的新手,我正在阅读 The Rust Programming Language 在线书籍。我现在遇到一个关于 Rust 借用检查的问题,代码示例如下所示:
fn first_word(s: &String) -> &str {
let bytes = s.as_bytes();
for (i, &b) in bytes.iter().enumerate() {
if b == b' ' {
return &s[..i];
}
}
&s[..]
}
fn main() {
let mut s = String::from("hello world");
let word = first_word(&s);
s.clear();
println!("word = {}", word);
}
Rust 编译器通过以下错误消息抱怨代码:
error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable
--> src/main.rs:16:5
|
15 | let word = first_word(&s);
| -- immutable borrow occurs here
16 | s.clear();
| ^^^^^^^^^ mutable borrow occurs here
17 |
18 | println!("word = {}", word);
| ---- immutable borrow later used here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0502`.
error: Could not compile `demo`.
To learn more, run the command again with --verbose.
在线书籍解释说,在执行s.clear() 时,会创建一个对s 的新可变引用,并与现有的不可变引用word 冲突,因为word 直到最后一个println! 才超出其范围陈述。似乎不知何故,Rust 的借用检查器发现 word(由 first_word 函数返回)指的是 s。它是如何实现的?
【问题讨论】:
-
@DenysSéguret:我猜这本书没有更新。
-
这在本书的Validating References with Lifetimes小节中有详细说明。我建议跳到该部分以了解 Rust 中的生命周期是如何工作的。
-
感谢您的回复。我只是尝试修改代码以直接从
first_word函数返回字符串文字,并且抱怨仍然存在。看来借用检查器是根据您刚才提到的生命周期做出决定的。我会读一下,谢谢。 -
@Lancern 借用检查器仅查看函数原型(即参数和返回类型)来确定输入和输出引用之间的关系。更改函数的实现不会改变函数在调用站点的处理方式。
-
为了返回引用,您必须将该引用与输入之一相关联。然后调用者可以负责提供一个足够长的输入以使用返回的引用。您根本无法返回任意引用;为了返回未连接到输入的内容,您必须返回(拥有的)项目而不是参考。
标签: rust