gpt4 book ai didi

rust - 为什么当范围内仍然存在不可变的借用字符串切片引用时,编译器不会在此可变借用上出错?

转载 作者:行者123 更新时间:2023-11-29 07:50:49 25 4
gpt4 key购买 nike

我正在从 The Rust Programming Language book available from No Starch Press 学习 Rust但遇到了一个问题,即编译器的行为与第 4 章第 1 页书中解释的不一样。 77.

本书的第 4 章讨论了所有权,以及第 1 页的示例。 77 与此类似,但 main() 中没有最后的 println!()(我还添加了注释和第 76 页中的函数以创建 MCVE)。 I also created a playground .

fn main() {
let mut s = String::from("Hello world!");
let word = first_word(&s);

// according to book, compiler should not allow this mutable borrow
// since I'm already borrowing as immutable, but it does allow it
s.clear();

// but of course I do get error here about immutable borrow later being
// used here, but shouldn't it have errored on the clear() operation before
// it got here?
println!("First word of s is \"{}\"", word);
}

// return string slice reference to first word in string or entire string if
// no space found
fn first_word(s: &String) -> &str {
let bytes = s.as_bytes();

for (i, &item) in bytes.iter().enumerate() {
if item == b' ' {
return &s[..i];
}
}

&s[..]
}

我理解为什么编译器会在当前位置抛出错误。但我从书中的理解是,当我试图清除字符串时,它应该导致编译器错误,因为我不能借用 s 作为可变的,因为它也被作为不可变的借用,从而消除了我收到错误的可能性(即,它不应该编译即使没有我的最终println!())。但只要我不尝试在 clear() 操作后使用对 word 的引用,它就可以正常编译。

这本书使用的是 Rust 1.21.0(参见 第 2 页),而我使用的是 Rust 1.31.0——所以这可能是编译器引入的一个变化,但我试图理解为什么。为什么像现在这样犯错比书中说会犯错的地方更好?

明确地说,我理解错误本身。我试图理解为什么它没有在书中所说的位置抛出编译器错误(即,为什么改变编译器行为?)。

最佳答案

这是由于 non-lexical lifetimes 而发生的变化,在最新版本的 Rust 中进行的更新(如果我没记错的话,在 Rust 1.31 引入的 2018 版中稳定了)。

在 Rust 的早期版本(包括本书所基于的版本)中,任何引用都应该在创建它的整个范围内有效(即,直到大括号结束)。如果您使用 word 删除该行并尝试在旧版本上编译代码,它会发出相同的错误 — “borrowed as mutable while borrowed as immutable”。

现在,借用检查器会跟踪引用是否真的被使用过。如果您没有在 s.clear() 之后使用 word,则假定可以在之前安全地删除对 s 的不可变引用s.clear() 采用可变代码,因此,正如您所提到的,这段代码将被安全地编译。当 println! 出现时,借用检查器发现不可变和可变借用的作用域相交,并准确地告诉您这一点 — 请注意错误分为三部分:

  1. 开始不可变借用,
  2. 开始可变借用,
  3. 不可变借用的使用。

关于rust - 为什么当范围内仍然存在不可变的借用字符串切片引用时,编译器不会在此可变借用上出错?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53954053/

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