Владение и перемещения
Поскольку переменные负责 освобождения своих собственных ресурсов, ресурсы могут иметь только одного владельца. Это также предотвращает освобождение ресурсов более одного раза. Обратите внимание, что не все переменные владеют ресурсами (например, [ссылки]).
При выполнении присваивания (let x = y
) или передаче аргументов функции по значению (foo(x)
), владение ресурсами передается. В терминах Rust это называется перемещением (move).
После перемещения ресурсов предыдущий владелец больше не может использоваться. Это избавляет от создания "проматывающихся" указателей.
// Эта функция получает владение памятью, выделенной на куче
fn destroy_box(c: Box<i32>) {
println!("Destroying a box that contains {}", c);
// `c` уничтожается и память освобождается
}
fn main() {
// _Стек_ выделенное целое число
let x = 5u32;
// *Копируем* `x` в `y` - никакие ресурсы не перемещаются
let y = x;
// Оба значения могут быть использованы независимо
println!("x is {}, and y is {}", x, y);
// `a` - это указатель на целое число, выделенное на _куче_
let a = Box::new(5i32);
println!("a contains: {}", a);
// *Перемещаем* `a` в `b`
let b = a;
// Адрес указателя `a` копируется (а не данные) в `b`.
// Теперь оба являются указателями на одну и ту же память, выделенную на куче, но
// `b` теперь владеет ею.
// Ошибка! `a` больше не может получить доступ к данным, потому что он больше не владеет
// памятью на куче
//println!("a contains: {}", a);
// TODO ^ Попробуйте раскомментировать эту строку
// Эта функция получает владение памятью, выделенной на куче из `b`
destroy_box(b);
// Поскольку память на куче уже освобождена в этом моменте, эта операция
// приведет к разыменованию освобожденной памяти, но это запрещено компилятором
// Ошибка! По той же причине, что и предыдущая ошибка
//println!("b contains: {}", b);
// TODO ^ Попробуйте раскомментировать эту строку
}