为啥 Rust 在 main 函数中没有返回值,以及如何返回值?

Posted

技术标签:

【中文标题】为啥 Rust 在 main 函数中没有返回值,以及如何返回值?【英文标题】:Why does Rust not have a return value in the main function, and how to return a value anyway?为什么 Rust 在 main 函数中没有返回值,以及如何返回值? 【发布时间】:2014-08-06 08:55:15 【问题描述】:

在 Rust 中,main 函数是这样定义的:

fn main() 


虽然这个函数不允许返回值。为什么一种语言不允许返回值,有没有办法返回一些东西?我能否安全地使用 C exit(int) 函数,或者这会导致泄漏等等?

【问题讨论】:

见this recent post on reddit too。 C 的exit 不好,因为它不运行析构函数。这将产生的主要副作用是缓冲区不会被刷新。例如如果您已写入 stdout 或 stderr,您的输出可能永远不会被写入,因为它们是缓冲的。 可能比这更严重。例如,在某些情况下,您可能最终无法绑定到您已经绑定了一两分钟的 TCP 端口(直到内核中的超时到期)。 @Mike:那是 system 缓冲区。在用户空间进行缓冲的地方(例如BufWriter),exit 不会刷新缓冲区。 还有这个 RFC 讨论:github.com/rust-lang/rfcs/issues/1176. 【参考方案1】:

std::process::exit(code: i32) 是用代码退出的方式。


Rust 这样做是为了有一个一致的显式接口来从程序返回一个值,无论它是从哪里设置的。如果main 启动了一系列任务,那么其中任何一个都可以设置返回值,即使main 已经退出。

Rust 确实有办法编写一个返回值的main 函数,但是它通常在 stdlib 中抽象出来。详情请见the documentation on writing an executable without stdlib。

【讨论】:

即使 main 已经退出 - 我的印象是当主线程退出时,整个程序都会退出。如果程序不退出,怎么能从 main 退出? 我不完全确定,我离开了this post,只是更新了这篇文章,希望在我进行更多研究的同时开始讨论它。 我怀疑这是因为 rust 使用了绿色线程。现在 rust 只使用 OS 线程,整个进程在 main 函数退出时确实退出,可能默认使用0 退出代码。【参考方案2】:

截至Rust 1.26,main 可以返回Result

use std::fs::File;

fn main() -> Result<(), std::io::Error> 
    let f = File::open("bar.txt")?;

    Ok(())

在这种情况下返回的错误代码是1,以防出错。使用 File::open("bar.txt").expect("file not found"); 代替,返回错误值 101(至少在我的机器上)。

另外,如果您想返回更一般的错误,请使用:

use std::error::Error;
...

fn main() -> Result<(), Box<dyn Error>> 
   ...

【讨论】:

@Lucretiel 不是真的,因为它没有说明为什么 Rust 没有 main 的返回值(默认情况下),而且这个解决方案没有说明如何指定自己的返回值(后者可能会造成自己的错误)。 @9769953 虽然有效的批评(你自己的答案!)我还是把它标记为正确答案。这个问题是在没有办法做到这一点的时候写的,现在有。在搜索从 main 中返回时,它也是排名靠前的结果之一,这个答案对于快速寻找答案的人来说是最有用的。【参考方案3】:

正如其他人所指出的,std::process::exit(code: i32) 是去这里的方式

RFC 1011: Process Exit 中提供了有关原因的更多信息。关于 RFC 的讨论在 the pull request of the RFC。

【讨论】:

【参考方案4】:

reddit thread on this 有一个“为什么”的解释:

Rust 当然可以设计来做到这一点。事实上,它曾经是。

但是由于 Rust 使用的任务模型,fn 主任务可以启动一堆其他任务然后退出!但其中一项任务可能需要在 main 消失后设置操作系统退出代码。

调用 set_exit_status 是明确的、简单的,并且不需要你总是在 main 的底部放一个 0,否则你不关心。

【讨论】:

您也不必在 C++ 中显式添加 return 0;(与 C 不同,在所有情况下,不从返回 int 的函数返回值都是 UB,即使对于 main 也是如此) . Rust 的解决方案看起来很相似,只是用另一种语法显式返回值。 从 C99 开始,main 函数的行为就像在它的末尾有一个 return 0; 语句,就像在 C++ 中一样。【参考方案5】:

您可以使用std::os::set_exit_status 设置返回值。

【讨论】:

这似乎不再是最新的了。 这个问题没有回答“为什么”。

以上是关于为啥 Rust 在 main 函数中没有返回值,以及如何返回值?的主要内容,如果未能解决你的问题,请参考以下文章

Rust hello world 语法解说

为啥main里的init函数没有执行

Rust hello world 语法讲解

为啥 int main() 编译?

为啥 main() 函数不返回浮点值?

Rust问答之从HelloWorld中可以学到什么