Я читал главу Хранение списков значений с векторами. Я пробовал пример Attempting to add an element to a vector while holding a reference to an item.
let mut _v: Vec<i32> = vec![2, 4, 6];
let _first = &_v[0];
_v.push(8);
println!("{:?}", _first);
Он не скомпилировался в соответствии с ожидаемым поведением. Согласно книге: -
When the program has a valid reference, the borrow checker enforces the ownership and borrowing rules (covered in Chapter 4) to ensure this reference and any other references to the contents of the vector remain valid. Recall the rule that states you can’t have mutable and immutable references in the same scope. That rule applies in Listing 8-7, where we hold an immutable reference to the first element in a vector and try to add an element to the end, which won’t work.
Но если я удалю последний оператор println, приведенный выше код скомпилируется. Я не могу понять, как макрос println! влияет на приведенное выше утверждение.
Пожалуйста, дайте мне знать, если я что-то упустил.

С введением Нелексические времена жизни (NLL) время жизни заимствований часто сокращается, если они не должны быть длиннее. Если вы попытаетесь скомпилировать свой пример без println! в версии Rust 2015 года (в которой, насколько мне известно, нет NLL), вы получите ошибку компиляции (ссылка на детскую площадку).
Даже с NLL оператор печати заставляет заимствование _v[0] длиться по крайней мере до тех пор, пока не будет выполнена печать. Но это означает, что заимствование начинается до и заканчивается после изменяемого заимствования _v.push(8). Этого не может быть, поскольку изменяемые заимствования должны быть исключительными заимствованиями.
Но без оператора печати заимствование _v[0] может закончиться сразу, позволяя произойти изменяемому заимствованию.
Имена переменных должны иметь префикс подчеркивания (
_), только если они не используются, но вы используете иv, иfirst.