Разнонаправленные функции в Rust

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

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

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

Введение

В этом лабе мы узнаем о发散函数, которые помечаются с использованием ! в Rust.发散函数 никогда не возвращают значения, и их тип возврата является пустым типом. Это отличается от типа (), который имеет только одно возможное значение.发散函数 могут быть полезны, когда требуется преобразование в любой другой тип, например, в ветках match. Они также являются типом возврата функций, которые бесконечно циклируют или завершают процесс.

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

#发散函数

发散函数 никогда не возвращают значения. Они помечаются с использованием !, который является пустым типом.

fn foo() ->! {
    panic!("This call never returns.");
}

В отличие от всех других типов, этот тип не может быть инстанциирован, потому что множество всех возможных значений, которое может иметь этот тип, пусто. Обратите внимание, что это отличается от типа (), который имеет ровно одно возможное значение.

Например, эта функция возвращает значение, как обычно, хотя в возвращаемом значении нет информации.

fn some_fn() {
    ()
}

fn main() {
    let _a: () = some_fn();
    println!("This function returns and you can see this line.");
}

В отличие от этой функции, которая никогда не вернет управление обратно вызывающей стороне.

#![feature(never_type)]

fn main() {
    let x:! = panic!("This call never returns.");
    println!("You will never see this line!");
}

Хотя это может показаться абстрактной концепцией, на самом деле она очень полезна и часто удобна в использовании. Главное преимущество этого типа заключается в том, что его можно преобразовать в любой другой тип и поэтому использовать в местах, где требуется точный тип, например, в ветках match. Это позволяет нам писать код такого вида:

fn main() {
    fn sum_odd_numbers(up_to: u32) -> u32 {
        let mut acc = 0;
        for i in 0..up_to {
            // Обратите внимание, что тип возврата этого выражения match должен быть u32
            // из-за типа переменной "addition".
            let addition: u32 = match i%2 == 1 {
                // Переменная "i" имеет тип u32, что совершенно нормально.
                true => i,
                // С другой стороны, выражение "continue" не возвращает
                // u32, но это все еще нормально, потому что оно никогда не возвращает и поэтому
                // не нарушает требования типов выражения match.
                false => continue,
            };
            acc += addition;
        }
        acc
    }
    println!("Sum of odd numbers up to 9 (excluding): {}", sum_odd_numbers(9));
}

Это также тип возврата функций, которые бесконечно циклируют (например, loop {}), как в случае с сетевыми серверами, или функций, которые завершают процесс (например, exit()).

Резюме

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