Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Перечисления

Ключевое слово enum позволяет создавать тип данных, который представляет собой один из нескольких возможных вариантов. Любой вариант, действительный как struct, также действителен как enum.

// Создаём `enum` для классификации web-событий. Обратите внимание,
// как имена и информация о типе определяют вариант:
// `PageLoad != PageUnload` и `KeyPress(char) != Paste(String)`.
// Все они разные и независимые.
enum WebEvent {
    // `enum` может быть как `unit-подобным`,
    PageLoad,
    PageUnload,
    // так и кортежной структурой,
    KeyPress(char),
    Paste(String),
    // или С-подобной структурой.
    Click { x: i64, y: i64 },
}

// Функция, которая получает на вход `WebEvent` и ничего не возвращает.
fn inspect(event: WebEvent) {
    match event {
        WebEvent::PageLoad => println!("страница загружена"),
        WebEvent::PageUnload => println!("страница выгружена"),
        // Извлечём `c` из `enum`.
        WebEvent::KeyPress(c) => println!("нажата '{}'.", c),
        WebEvent::Paste(s) => println!("нажата \"{}\".", s),
        // Разберём `Click` на `x` и `y`.
        WebEvent::Click { x, y } => {
            println!("кликнуто на x={}, y={}.", x, y);
        },
    }
}

fn main() {
    let pressed = WebEvent::KeyPress('x');
    // `to_owned()` создаст `String` из строкового среза.
    let pasted  = WebEvent::Paste("мой текст".to_owned());
    let click   = WebEvent::Click { x: 20, y: 80 };
    let load    = WebEvent::PageLoad;
    let unload  = WebEvent::PageUnload;

    inspect(pressed);
    inspect(pasted);
    inspect(click);
    inspect(load);
    inspect(unload);
}

Псевдонимы типов

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

enum VeryVerboseEnumOfThingsToDoWithNumbers {
    Add,
    Subtract,
}

// Создаётся псевдоним типа
type Operations = VeryVerboseEnumOfThingsToDoWithNumbers;

fn main() {
    // Мы можем обратиться к каждому варианту перечисления через его
    // псевдоним, а не через его длинное неудобное имя.
    let x = Operations::Add;
}

Самое частое место, где можно это увидеть, — impl-блоки, которые используют Self.

#![allow(unused)]
fn main() {
enum VeryVerboseEnumOfThingsToDoWithNumbers {
    Add,
    Subtract,
}

impl VeryVerboseEnumOfThingsToDoWithNumbers {
    fn run(&self, x: i32, y: i32) -> i32 {
        match self {
            Self::Add => x + y,
            Self::Subtract => x - y,
        }
    }
}
}

Чтобы больше узнать о перечислениях и псевдонимах типов, вы можете почитать отчёт о стабилизации, в котором эта возможность была включена в Rust.

Смотрите также:

match, fn, String и “Type alias enum variants” RFC