在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的可执行文件的文档。
如函数文档中所述,这将立即退出而不运行任何析构函数,因此应谨慎使用:
注意,因为这个函数永远不会返回,并且它会终止进程,所以不会运行当前堆栈或任何其他线程堆栈上的析构函数。如果需要彻底关闭,建议只在没有更多析构函数可运行的情况下调用此函数。
正如其他人所指出的,std::process::exit(code: i32)
是这里的方法
关于原因的更多信息在RFC 1011:进程退出中给出。关于RFC的讨论在RFC的pull request中
关于这个的reddit帖子有一个"为什么";解释:
Rust当然可以设计成这样。事实上,过去是这样的。
但是由于Rust使用的任务模型,fn主任务可以启动一堆其他任务,然后退出!但是其中一个任务可能想要在main退出后设置操作系统退出代码。
调用set_exit_status是显式的,简单的,并且当你不关心的时候,不需要你总是在main的底部放一个0。
尝试:
use std::process::ExitCode;
fn main() -> ExitCode {
ExitCode::from(2)
}
看一下doc
或:
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
设置返回值