Проанализируйте этот фрагмент Rust: "let x = String::from(\"hello\"); let y = x; println!(\"{}\", x);" — объясните, почему он не компилируется и как правильно передать владение или ссылку
Причина: тип `String` не реализует трейт `Copy`, поэтому присваивание `let y = x;` переносит (move) владение строки из `x` в `y`. После этого `x` становится недействительным и использование `x` вызывает ошибку компилятора ("use of moved value"). Примеры решений. 1) Передать владение (move) и далее пользоваться `y`: ``` let x = String::from("hello"); let y = x; // x moved into y println!("{}", y); // OK — используем y // println!("{}", x); // ошибка: x был перемещён ``` 2) Скопировать данные (глубокая копия) — сохранить `x` тоже: ``` let x = String::from("hello"); let y = x.clone(); // clone делает глубокую копию println!("{}", x); // OK println!("{}", y); // OK ``` 3) Передать ссылку (borrow) — владение не меняется: ``` let x = String::from("hello"); let y = &x; // y — ссылка на x println!("{}", x); // OK println!("{}", y); // OK (fmt через Deref) ``` 4) Если нужно изменять через ссылку — mutable borrow (и тогда нельзя использовать `x` пока действует заимствование): ``` let mut x = String::from("hello"); let y = &mut x; // mutable borrow y.push_str("!"); println!("{}", y); // OK // println!("{}", x); // ошибка: x заимствовано как mutable ``` Кратко: либо передавайте владение и дальше используйте тот объект, куда владелец перемещён; либо клонируйте, либо передавайте ссылку (`&` или `&mut`) в зависимости от потребности.
Примеры решений.
1) Передать владение (move) и далее пользоваться `y`:
```
let x = String::from("hello");
let y = x; // x moved into y
println!("{}", y); // OK — используем y
// println!("{}", x); // ошибка: x был перемещён
```
2) Скопировать данные (глубокая копия) — сохранить `x` тоже:
```
let x = String::from("hello");
let y = x.clone(); // clone делает глубокую копию
println!("{}", x); // OK
println!("{}", y); // OK
```
3) Передать ссылку (borrow) — владение не меняется:
```
let x = String::from("hello");
let y = &x; // y — ссылка на x
println!("{}", x); // OK
println!("{}", y); // OK (fmt через Deref)
```
4) Если нужно изменять через ссылку — mutable borrow (и тогда нельзя использовать `x` пока действует заимствование):
```
let mut x = String::from("hello");
let y = &mut x; // mutable borrow
y.push_str("!");
println!("{}", y); // OK
// println!("{}", x); // ошибка: x заимствовано как mutable
```
Кратко: либо передавайте владение и дальше используйте тот объект, куда владелец перемещён; либо клонируйте, либо передавайте ссылку (`&` или `&mut`) в зависимости от потребности.