Почему строковый литерал не перемещается?

Я просматривал второе издание электронной книги по Rust и в фрагменте кода из связанной главы, если я удалю оператор ссылки (&) в строке 3, программа все равно будет работать отлично.

let mut s1 = String::from("foo");
let s2 = "bar";
s1.push_str(&s2); // here
println!("s2 is {}", s2);

Значение s2 должно быть перемещено в соответствии с книгой. Однако, если я изменю

s1.push_str(&s2);

to

s1.push_str(s2);

следующая строка должна вызвать ошибку, но этого не происходит:

println!("s2 is {}", s2);

Фрагмент из документации:

Листинг 8-16: Использование фрагмента строки после добавления его содержимого к строке Если бы метод push_str стал владельцем s2, мы не смогли бы распечатать его значение в последней строке. Однако этот код работает так, как мы и ожидали!

Я использую Rust 1.24.1.


person Kajal Sinha    schedule 21.03.2018    source источник


Ответы (1)


Подпись push_str:

pub fn push_str(&mut self, string: &str)

Это означает, что его аргумент является ссылкой. Это соответствует типу s2, который является ссылкой на срез статической строки:

let s2: &'static str = "bar";

Компилятор может разыменовывать аргумент push_str столько раз, сколько необходимо, поэтому s1.push_str(s2) работает так же хорошо, как s1.push_str(&&&&&s2).

Поскольку в конце концов вы всегда передаете ссылку, аргумент не перемещается (только заимствуется), и s2 по-прежнему доступен после его отправки.

person ljedrz    schedule 21.03.2018
comment
На самом деле важная часть заключается в том, что &str: Copy, как и все неизменяемые ссылки. - person Shepmaster; 21.03.2018