gpt4 book ai didi

rust - 如何知道借用何时结束

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

我写这个是为了简单的输入解析:

use std::io;

fn main() {
let mut line = String::new();

io::stdin().read_line(&mut line)
.expect("Cannot read line.");

let parts = line.split_whitespace();

for p in parts {
println!("{}", p);
}

line.clear();
io::stdin().read_line(&mut line)
.expect("Cannot read line.");

}

上面的代码创建了一个 String 对象,将一行读入其中,用空格分割并打印输出。然后它尝试使用相同的 String 对象执行相同的操作。编译时出现错误:

  --> src/main.rs:15:5
|
9 | let parts = line.split_whitespace();
| ---- immutable borrow occurs here
...
15 | line.clear();
| ^^^^ mutable borrow occurs here
...
19 | }
| - immutable borrow ends here

因为 Stringowned by an iterator .解决方案描述为:

let parts: Vec<String> = line.split_whitespace()
.map(|s| String::from(s))
.collect();

我有几个问题:

  1. 我已经通过调用每个迭代器来使用迭代器。它的借用应该已经结束。
  2. 我如何知道从函数定义中借用的生命周期?
  3. 如果一个函数正在借用一个对象,我怎么知道它释放了它?例如在解决方案中使用 collect() 释放借用。

我想我在这里遗漏了一个重要的概念。

最佳答案

您的代码中的问题是您将 line.split_whitespace() 的结果绑定(bind)到一个名称(parts)。如果你这样写:

io::stdin().read_line(&mut line)
.expect("Cannot read line.");

for p in line.split_whitespace() { // <-- pass directly into loop
println!("{}", p);
}

line.clear();
io::stdin().read_line(&mut line)
.expect("Cannot read line.");

这样就可以了。另一种可能性是人为地限制 parts 的生命周期,如下所示:

io::stdin().read_line(&mut line)
.expect("Cannot read line.");

{
let parts = line.split_whitespace();

for p in parts {
println!("{}", p);
}
}

line.clear();
io::stdin().read_line(&mut line)
.expect("Cannot read line.");

这也行。


那是为什么呢?这是由于编译器当前的工作方式,通常称为“词法借用”。这里的问题是每个包含借用的非临时值都将“有效”,直到其作用域结束。

在您的情况下:由于您将 split_whitespace()(借用字符串)的结果分配给 parts,因此借用在范围结束之前一直“有效” 部分直到零件的使用生命周期结束。

在这个答案的第一个版本中,我们没有将名称绑定(bind)到值,因此 split_whitespace() 的结果只是一个临时的,借用不会扩展到全范围。这也是您的 collect() 示例起作用的原因:不是因为 collect(),而是因为从来没有名称绑定(bind)到借用字符串的东西。在我的第二个版本中,我们只是限制范围。

请注意,这是编译器的一个已知缺点。你是对的,编译器只是看不到它。

关于rust - 如何知道借用何时结束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45522745/

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