#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
больше не читается. Вы могли бы назначить ему новую строку, но вы не можете прочитать ту, которая была удалена.