发散函数 - Rust By Example
Description: Rust by Example (RBE) is a collection of runnable examples that illustrate various Rust concepts and standard libraries.

## 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

# 发散函数

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

    #![allow(unused)]
    fn main() {
    fn foo() -> ! {
        panic!("此调用永不返回。");
    }
    }

与所有其他类型相反，这个类型不能被实例化，因为这个类型可能拥有的所有可能值的集合是空的。注意，它与 `()` 类型不同，后者恰好有一个可能的值。

例如，这个函数像往常一样返回，尽管返回值中没有任何信息。

    fn some_fn() {
        ()
    }

    fn main() {
        let _a: () = some_fn();
        println!("这个函数返回了，你可以看到这一行。");
    }

与之相对的是这个函数，它永远不会将控制权返回给调用者。

    #![feature(never_type)]

    fn main() {
        let x: ! = panic!("此调用永不返回。");
        println!("你永远不会看到这一行！");
    }

虽然这看起来像是一个抽象概念，但它实际上非常有用且经常派上用场。这种类型的主要优势是它可以被转换为任何其他类型，这使得它在需要精确类型的情况下非常灵活，比如在 match 分支中。这种灵活性允许我们编写如下代码：

    fn main() {
        fn sum_odd_numbers(up_to: u32) -> u32 {
            let mut acc = 0;
            for i in 0..up_to {
                // 注意这个 match 表达式的返回类型必须是 u32，
                // 因为 "addition" 变量的类型是 u32。
                let addition: u32 = match i%2 == 1 {
                    // "i" 变量的类型是 u32，这完全没问题。
                    true => i,
                    // 另一方面，"continue" 表达式不返回 u32，
                    // 但这仍然可以，因为它永远不会返回，
                    // 因此不违反 match 表达式的类型要求。
                    false => continue,
                };
                acc += addition;
            }
            acc
        }
        println!("9 以下（不包括 9）的奇数之和：{}", sum_odd_numbers(9));
    }

它也是永远循环的函数（例如 `loop {}`）的返回类型，比如网络服务器，或终止进程的函数（例如 `exit()`）。