当 运行 next 在不可变迭代器上时不能作为可变借用(没有其他借用)

Cannot borrow as mutable when running next on an immutable iterator (no other borrows)

尝试运行以下代码时:

fn main() {
    let s1 = String::from("hello world");
    println!("The first word in the string is: {}", return_first_word(&s1));
}

fn return_first_word(s: &String) -> String {
    let t = s.split(" ");
    String::from(t.next().unwrap())
}

我在 String::from(t.next().unwrap()) 行收到错误 cannot borrow as mutable。当然,当我将 let t = ... 行替换为 let mut t = ... 时,代码可以完美运行。

我的问题是,有人可以解释为什么吗?这里借用了什么,借用了什么?我检查了我新创建的不可变变量 t 的类型,它是一个迭代器。为什么迭代迭代器会出现问题?

如果您熟悉 Java 这样的语言,您可能会期望 str::split 到 return 数组,但实际上不是。在 Rust 中,str::split return 是一个迭代器。它实际上并没有立即拆分整个字符串;它为您提供了一个特殊的迭代器对象,它在 作为 您遍历字符串时执行此操作。

现在,迭代在 Rust 中是一个有状态的过程。要迭代某些内容,您可以调用 Iterator::next,它会更改迭代器的内部状态并生成下一个值。如果重复调用,它会按顺序为您提供迭代器的每个值,然后开始生成 None。由于 next 改变了迭代器的状态,它必须有一个指向迭代器的可变引用。

当你在 Rust 中用 let 声明一个变量时,它是不可变的。你无法改变它。您已经告诉 Rust 系统您无意更改它。因此,当您尝试对您承诺永远不会更改的事物(在您的情况下为迭代器)进行可变引用时,Rust 会抱怨。相反,您需要使用 let mut 来表明您的意图。