Деструктуризация и разыменовывание в Rust

Beginner

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

Введение

В этом лабе мы исследуем концепции деструктуризации и разыменовывания в Rust, подчеркивая различия в их использовании по сравнению с такими языками, как C/C++. Деструктуризация заключается в использовании &, ref и ref mut для присвоения и сопоставления ссылок, а разыменовывание выполняется с использованием * для доступа к значению, на которое указывает ссылка.

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

Указатели/ссылки

При работе с указателями необходимо различать деструктуризацию и разыменовывание, так как это разные концепции, которые используются по-разному по сравнению с такими языками, как C/C++.

  • Для разыменовывания используется *
  • Для деструктуризации используются &, ref и ref mut
fn main() {
    // Назначаем ссылку типа `i32`. Символ `&` означает, что
    // присваивается ссылка.
    let reference = &4;

    match reference {
        // Если `reference` сопоставляется с образцом `&val`, то это
        // эквивалентно сравнению вида:
        // `&i32`
        // `&val`
        // ^ Мы видим, что если убирать сопоставляющие `&`, то `i32`
        // должно быть присвоено `val`.
        &val => println!("Получено значение при деструктуризации: {:?}", val),
    }

    // Чтобы избежать `&`, нужно выполнить разыменование перед сопоставлением.
    match *reference {
        val => println!("Получено значение при разыменовании: {:?}", val),
    }

    // Что если не начинать с ссылки? `reference` была ссылкой,
    // потому что правая сторона уже была ссылкой. Здесь это не ссылка,
    // потому что правая сторона не является ссылкой.
    let _not_a_reference = 3;

    // Для таких случаев Rust предоставляет `ref`. Он изменяет
    // присваивание так, чтобы для элемента создавалось и
    // присваивалось ссылка.
    let ref _is_a_reference = 3;

    // Соответственно, определив 2 значения без ссылок, можно
    // получить ссылки с помощью `ref` и `ref mut`.
    let value = 5;
    let mut mut_value = 6;

    // Используем ключевое слово `ref` для создания ссылки.
    match value {
        ref r => println!("Получена ссылка на значение: {:?}", r),
    }

    // Аналогично используем `ref mut`.
    match mut_value {
        ref mut m => {
            // Получили ссылку. Необходимо выполнить разыменование,
            // прежде чем можно что-то добавить к ней.
            *m += 10;
            println!("Мы добавили 10. `mut_value`: {:?}", m);
        },
    }
}

Резюме

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