I am learning Rust from The Rust Programming Language book available from No Starch Press but ran into an issue where the compiler did not behave as explained in the book in chapter 4 on p. 77.
Chapter 4 of the book is discussing ownership, and the example on p. 77 is similar to this without the final println!()
in main()
(I've also added comments and the function from p. 76 to create an 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[..]
}
I understand why the compiler throws an error where it currently does. But my understanding from the book is that it should have caused a compiler error when I tried to clear the string because I cannot borrow s
as mutable because it is also borrowed as immutable, thus eliminating the possibility of the error I received (i.e., it should not compile even without my final println!()
). But it compiles fine for me so long as I don't try to use the reference to word
after the clear()
operation.
The book is using Rust 1.21.0 (see p. 2) whereas I am using Rust 1.31.0—so this is likely a change that has been introduced to the compiler, but I am trying to understand why. Why is it better to error as it currently does versus where the book said it would error?
To be clear, I understand the errors themselves. I'm trying to understand why it doesn't throw a compiler error in the location the book says it should (i.e., why the change in compiler behavior?).