Правила владения
Владение — самая уникальная особенность Rust, обеспечивающая безопасность памяти без сборщика мусора. Три правила управляют владением:
- У каждого значения есть ровно один владелец (переменная)
- Когда владелец выходит из области видимости, значение освобождается
- Одновременно может быть только один владелец
fn main() {
let s1 = String::from("hello");
let s2 = s1; // s1 ПЕРЕМЕЩАЕТСЯ в s2
// println!("{}", s1); // ❌ s1 больше недействителен!
println!("{}", s2); // ✅ "hello"
}
Clone — глубокое копирование
let s1 = String::from("hello");
let s2 = s1.clone(); // явное глубокое копирование
println!("{} и {}", s1, s2); // оба действительны
Заимствование через ссылки
Ссылки позволяют обращаться к значению без передачи владения:
fn calculate_length(s: &String) -> usize {
s.len() // только заимствуем, владение не передаётся
}
let s1 = String::from("hello");
let len = calculate_length(&s1); // передаём ссылку
println!("Длина '' {}' равна {}", s1, len); // s1 по-прежнему действителен
Изменяемые ссылки
fn change(s: &mut String) {
s.push_str(", world");
}
let mut s = String::from("hello");
change(&mut s);
println!("{}", s); // "hello, world"
// Правила: только ОДНА изменяемая ссылка одновременно
// и нельзя одновременно иметь изменяемую и неизменяемую ссылки
Срезы
let s = String::from("hello world");
let hello = &s[0..5]; // срез: "hello"
let world = &s[6..11]; // срез: "world"
println!("{} {}", hello, world);
// Срезы массивов
let arr = [1, 2, 3, 4, 5];
let slice = &arr[1..3]; // [2, 3]
println!("{:?}", slice);