在 Rust 中,main 函数的定义如下:
fn main() {
}
此函数不允许返回值。为什么语言不允许返回值并且有没有办法返回某些东西?我是否能够安全地使用 C
exit(int)
功能,或者这会导致泄漏等问题吗?
从 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>> {
...
}
这不再是以状态退出的推荐方法,请参阅有关从 main 返回和实现 Termination
的其他答案std::process::exit(code: i32)
是用代码退出的方式。
Rust 这样做是为了有一个一致的显式接口来从程序返回值,无论它是从哪里设置的。如果
main
启动一系列任务,那么其中任何一个都可以设置返回值,即使 main
已经退出。
Rust 确实有办法编写返回值的
main
函数,但它通常是在 stdlib 中抽象的。有关详细信息,请参阅有关在不使用 stdlib 的情况下编写可执行文件的文档。
如函数文档中所述,这将立即退出而不运行任何析构函数,因此应小心使用:
请注意,由于该函数永远不会返回,并且它会终止进程,因此当前堆栈或任何其他线程堆栈上的析构函数不会运行。如果需要干净关闭,建议仅在没有更多析构函数可运行的已知点调用此函数。
reddit 主题 有一个“为什么”解释:
Rust 当然可以被设计来做到这一点。事实上,以前也是这样。但是由于 Rust 使用的任务模型,fn 主任务可以启动一堆其他任务然后退出!但其他任务之一可能需要在 main 消失后设置操作系统退出代码。
调用 set_exit_status 是明确的、简单的,并且不需要您在不关心的情况下总是在 main 的底部放置 0。
use std::process::ExitCode;
fn main() -> ExitCode {
ExitCode::from(2)
}
或:
use std::process::{ExitCode, Termination};
pub enum LinuxExitCode { E_OK, E_ERR(u8) }
impl Termination for LinuxExitCode {
fn report(self) -> ExitCode {
match self {
LinuxExitCode::E_OK => ExitCode::SUCCESS,
LinuxExitCode::E_ERR(v) => ExitCode::from(v)
}
}
}
fn main() -> LinuxExitCode {
LinuxExitCode::E_ERR(3)
}
std::os::set_exit_status
设置返回值。