【发布时间】:2019-05-26 00:21:18
【问题描述】:
我正在从The Rust Programming Language book available from No Starch Press 学习 Rust,但遇到了一个问题,即编译器的行为与本书第 4 章 p. 77.
本书的第 4 章讨论了所有权,以及第 4 页的示例。 77 与 main() 中没有最终的 println!() 类似(我还添加了 cmets 和第 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——所以这可能是编译器引入的一个变化,但我是试图理解为什么。为什么像现在这样出错而不是书中所说的出错更好?
明确地说,我自己理解错误。我试图理解为什么它不会在本书所说的位置引发编译器错误(即,为什么在编译器行为?)。
【问题讨论】:
-
是因为NLL功能,
-
请注意,您是在 2018 年版中进行编码。这本书是 2015 年版的主要书籍。
-
@Stargateur 非常令人失望,因为这本书几个月前才出版......在 2018 年!
-
@Dan 很抱歉给您带来不便,如果您想了解所有差异,这里有一个很好的资源,doc.rust-lang.org/edition-guide/introduction.html。有很棒的新功能所以不要失望;)