Appearance
33.4 main 函数中使用问号运算符
新加入的问号运算符给main
函数带来了一个挑战。因为问号运算符会 return 一个 Result 类型,如果它所处的函数签名不是返回的 Result 类型,一定会出现类型匹配错误。而main
函数一开始的时候是定义成fn() -> ()
类型的,所以问号运算符不能在 main 函数中使用。这显然是一个问题,解决这个问题的办法就是——修改 main 函数的签名类型。
我们希望:main
函数既可以返回 unit 类型,不破坏以前的旧代码;又可以返回 Result 类型,支持使用问号运算符。所以,最简单的办法就是使用泛型,兼容这两种类型。
Rust 在标准库中引入了一个新的 trait:
rust
pub trait Termination {
/// Is called to get the representation of the value as status code.
/// This status code is returned to the operating system.
fn report(self) -> i32;
}
main 函数的签名就对应地改成了fn<T: Termination>() -> T
。标准库为 Result 类型、()类型、bool 类型以及发散类型!实现了这个 trait。所以这些类型都可以作为 main 函数的返回类型了。
它是怎么启动起来的呢?是因为 Runtime 库中有这样的一个函数,它调用了用户写的main
函数:
rust
#[lang = "start"]
fn lang_start<T: ::termination::Termination + 'static>
(main: fn() -> T, argc: isize, argv: *const *const u8) -> isize
{
lang_start_internal(&move || main().report(), argc, argv)
}
在最终的可执行代码中,程序刚启动的时候要先执行一些 Runtime 自带的逻辑,然后才会进入用户写的main
函数中去。