Запрос о добавленной стоимости для переменной

#rust

Вопрос:

Код 1:

 let x = 1;
let y = x 1;
println!("{}",y);
println!("{}",x);
 

Код 2:

 let mut s2 = String::from("Tôi tên là");
let s4 = s2;
println!("{}",s4);
println!("{}",s2);
 

Почему x в коде 1 имеет значение, а s2 в коде 2 не имеет значения.

Ответ №1:

По умолчанию, когда вы используете переменную в Rust без ссылки, вы перемещаете значение из этой переменной.

 let mut s2 = String::from("Tôi tên là");
let s4 = s2;
 

Вот, s2 владеет строкой, затем мы перемещаем строку в s4 . В это время у s2 него больше нет никаких действительных данных, так как ранее принадлежавшая ему стоимость переместилась куда-то еще.

Теперь самый типичный способ обойти это-клонировать значение. Большинство встроенных типов могут быть клонированы, и если вы клонируете значение, то получаете идентичное значение, которое не имеет прямого отношения к оригиналу.

 let mut s2 = String::from("Tôi tên là");
let s4 = s2.clone();
 

Теперь s2 и s4 то, и другое указывает на две несвязанные, допустимые строки, которые выглядят совершенно одинаково.

Однако разработчики Rust были достаточно умны, чтобы понять, что это не всегда оптимально. Для простых типов, таких как числа, нет смысла применять право собственности (что, черт возьми, значит «владеть» числом 2?). Для типов, где «клонировать» просто означает «копировать значение по битам», у нас есть еще одна особенность: Copy . Числовые типы в реализации Rust Copy , которая эффективно автоматически вводит clone в ваш код всякий раз, когда вы перемещаете значение. Так что это

 let x = 1;
let y = x 1;
 

Поскольку x это «простой» тип, такой как число, Rust автоматически делает что-то подобное

 let x = 1;
let y = x.clone()   1;
 

и ваша первоначальная стоимость остается в силе.

Струны не могут быть Copy . Как я уже сказал, Copy включает в себя побитовую копию фактических данных. В Rust a String -это указатель на некоторую выделенную память и размер. Поскольку String предполагает некоторое косвенное использование, его clone метод должен быть умным и выполнять глубокое копирование, поэтому мы не можем использовать Copy простое побитовое копирование, как для чисел.

Ответ №2:

В первой программе переменные имеют тип i32 , который таков Copy . Copy типы копируются, а не перемещаются, поэтому x их все еще можно использовать после использования их значения.

Во второй программе String этого нет Copy , поэтому при назначении s2 s4 строка перемещается. Право собственности передается от s2 к s4 и s2 больше не читается. Вы могли бы назначить ему новую строку, но вы не можете прочитать ту, которая была удалена.