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

Diverging functions

Функції розбіжності ніколи не повертають. Їх позначають за допомогою !, який є порожнім типом.

#![allow(unused)]
fn 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 {
            // Notice that the return type of this match expression must be u32
            // because of the type of the "addition" variable.
            let addition: u32 = match i%2 == 1 {
                // The "i" variable is of type u32, which is perfectly fine.
                true => i,
                // On the other hand, the "continue" expression does not return
                // u32, but it is still fine, because it never returns and therefore
                // does not violate the type requirements of the match expression.
                false => continue,
            };
            acc += addition;
        }
        acc
    }
    println!("Sum of odd numbers up to 9 (excluding): {}", sum_odd_numbers(9));
}

Це також є типом повернення функцій, які працюють у нескінченному циклі (наприклад, loop {}), як-от мережеві сервери або функції, що завершують процес (наприклад, exit()).