Владение и Перемещения

RustRustBeginner
Практиковаться сейчас

This tutorial is from open-source community. Access the source code

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В этом лабе объясняется, что в Rust переменные обладают ресурсами и могут иметь только одного владельца, что предотвращает освобождение ресурсов несколько раз. Когда переменным присваивается значение или аргументы функции передаются по значению, владение ресурсами передается, что называется перемещением (move). После перемещения предыдущий владелец больше не может использоваться, чтобы избежать создания "проматывающихся" указателей. Пример кода демонстрирует эти концепции, показывая, как передается владение переменным, размещенным на стеке и куче, и как обращение к переменной после перемещения ее владения приводит к ошибкам.

Примечание: Если в лабе не указано имя файла, вы можете использовать любое имя, которое хотите. Например, вы можете использовать main.rs, скомпилировать и запустить его с помощью rustc main.rs &&./main.

Владение и перемещения

Поскольку переменные负责 освобождения своих собственных ресурсов, ресурсы могут иметь только одного владельца. Это также предотвращает освобождение ресурсов более одного раза. Обратите внимание, что не все переменные владеют ресурсами (например, [ссылки]).

При выполнении присваивания (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 ^ Попробуйте раскомментировать эту строку
}

Резюме

Поздравляем! Вы завершили лабу по Владению и Перемещениям. Вы можете практиковаться в других лабах в LabEx, чтобы улучшить свои навыки.