发散函数

发散函数永不返回。它们使用 ! 标记,它是一个空类型。

#![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())。