阅读Rust书,我遇到了an interesting topic — divergent functions:
Rust为'发散功能'提供了一些特殊的语法 不返回的函数:
fn diverges() -> ! { panic!("This function never returns!"); }
分歧功能可以用作任何类型:
let x: i32 = diverges(); let x: String = diverges();
发散功能的用例是什么?这本书说明了
panic!()
导致当前执行线程崩溃 给出消息。因为这个功能会导致崩溃,所以永远不会 返回,因此它具有类型!
这是有道理的,但我无法想到其他地方会使用不同的功能,并且似乎非常本地化为panic!
。我知道必须有一些有用的场景,为什么他们引入了不同的功能。在Rust哪里可能会看到不同的功能?
答案 0 :(得分:37)
它有几个用途。它可用于设计用于恐慌或退出程序的功能。 panic!()
本身就是一个这样的函数,但它也可以应用于包装panic!()
的函数,例如打印出更详细的错误信息然后恐慌。
它也可以用于永不返回的功能。如果函数进入无限循环,例如服务器的主循环,因此永远不会返回,则可以这样定义。
另一种可能的用法是围绕Unix exec
family of functions的包装器,其中当前进程被正在执行的进程替换。
拥有这样的类型很有用,因为它与所有其他类型兼容。为了保证类型安全,Rust必须确保match
或if
语句的所有分支都返回相同的类型。但是如果有一些分支无法访问或指示错误,则需要某种方法来抛出将与其他分支返回的类型统一的错误。由于!
与所有类型统一,因此可以在任何此类情况下使用。
目前有一个interesting RFC(和discussion)在expanding the places where !
can be used争论(部分),认为它应该被视为完整的类型{{1是的; ()
是一种没有与所有其他类型统一的值的类型,而!
是具有单个值的不同类型。我不确定我是否同意完整的RFC,但是将()
视为完整类型的讨论很有意思,我认为可以与RFC的其余部分分开提出。
更新:自从我上面写了以后,关于将!
提升为完整版本的RFC的部分是split into a separate RFC and merged,并且是in the process of being implemented(目前可用于功能门后的夜间构建)。作为一个完整的类型,它可以在更多的上下文中使用,例如在!
中表示永远不会失败的结果,或Result<T, !>
作为永远不会成功的结果。这些在通用上下文中很有用;如果你有一些需要方法来返回结果的特性,但对于那个特定的实现它只能成功,你不需要填写一些虚拟错误类型。
答案 1 :(得分:13)
正如您在本书中引用的那样,Rust bottom type用于指定不返回的函数。这包括:
panic!()
main()
返回除外),例如exit(),其签名为pub fn exit(code: i32) -> !