我正在学习Rust,参考了No Starch Press出版的The Rust Programming Language一书。但是在第四章的第77页中,编译器的行为与书中讲解不符,遇到了问题。
该书的第四章讨论所有权,在第77页的示例类似于这个示例,只是在
我理解编译器为什么会在当前位置抛出错误。但是根据这本书的理解,当我尝试清空字符串时,它应该会引起编译器错误,因为我不能将`s`作为可变借用,因为它也被借用为不可变,从而消除了我收到的错误的可能性(即,即使没有我的最后一个`println!()`,它也不应该编译)。但只要我在`clear()`操作后不尝试使用对`word`的引用,它就可以正常编译。
这本书使用的是Rust 1.21.0(请参见第2页),而我使用的是Rust 1.31.0-所以这可能是编译器引入的更改,但我正在努力理解为什么。为什么它现在抛出错误比书中说的位置更好?
明确一点,我理解错误本身。我正在尝试理解为什么它没有在书中指定的位置抛出编译器错误(即为什么编译器行为发生了变化?)。
该书的第四章讨论所有权,在第77页的示例类似于这个示例,只是在
main()
中没有最后的println!()
(我还添加了注释和第76页的函数以创建MCVE)。我还创建了一个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-所以这可能是编译器引入的更改,但我正在努力理解为什么。为什么它现在抛出错误比书中说的位置更好?
明确一点,我理解错误本身。我正在尝试理解为什么它没有在书中指定的位置抛出编译器错误(即为什么编译器行为发生了变化?)。