Основы владения и заимствования в Rust

Beginner

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

Введение

В этом лабе мы узнаем о заимствовании в Rust, которое позволяет получать доступ к данным без передачи владения, используя ссылки ('&T') вместо передачи объектов по значению ('T'). Проверщик заимствований гарантирует, что ссылки всегда указывают на валидные объекты и предотвращает уничтожение объектов, которые используются в качестве заимствования.

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

Заимствование

Большинство времени мы хотим получать доступ к данным, не передавая владение ими. Для этого Rust использует механизм заимствования. Вместо передачи объектов по значению (T), объекты могут быть переданы по ссылке (&T).

Компилятор статически гарантирует (через проверщик заимствований), что ссылки всегда указывают на валидные объекты. То есть, пока существуют ссылки на объект, объект не может быть уничтожен.

// Эта функция получает владение ящиком и уничтожает его
fn eat_box_i32(boxed_i32: Box<i32>) {
    println!("Destroying box that contains {}", boxed_i32);
}

// Эта функция заимствует i32
fn borrow_i32(borrowed_i32: &i32) {
    println!("This int is: {}", borrowed_i32);
}

fn main() {
    // Создаем ящик с i32 и стековый i32
    let boxed_i32 = Box::new(5_i32);
    let stacked_i32 = 6_i32;

    // Заимствуем содержимое ящика. Владение не передается,
    // поэтому содержимое можно заимствовать снова.
    borrow_i32(&boxed_i32);
    borrow_i32(&stacked_i32);

    {
        // Получаем ссылку на данные, содержащиеся внутри ящика
        let _ref_to_i32: &i32 = &boxed_i32;

        // Ошибка!
        // Не удается уничтожить `boxed_i32`, пока внутреннее значение заимствовано позже в области видимости.
        eat_box_i32(boxed_i32);
        // FIXME ^ Закомментируйте эту строку

        // Пытаемся заимствовать `_ref_to_i32` после уничтожения внутреннего значения
        borrow_i32(_ref_to_i32);
        // `_ref_to_i32` выходит из области видимости и больше не заимствуется.
    }

    // Теперь `boxed_i32` может передать владение `eat_box` и быть уничтоженным
    eat_box_i32(boxed_i32);
}

Резюме

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