在Rust中,如果主函数返回错误会发生什么?

发布于 2025-01-25 03:30:59 字数 1882 浏览 2 评论 0原文

根据 >

如果存在MAIN函数(SNIP),并且其返回类型必须是以下内容之一:

  • ()

  • 结果<(),e>其中e:错误

,但没有说main()返回()ok(())err(< value>)

就我测试而言

()ok(())err(< value>)
状态001
附加行为-退出错误:&lt ; value>被打印到stderr

是否在某些文档中定义,明确解释或保证了这些行为?特别是,我可以假设

  • 1状态时,程序始终可以在main(main()返回err(< value>)时?

  • main(Main()返回err(< value>)始终为form 错误:< value> ?


注意:

  • 我想要某种记录的保证,而不是经验解释。这就是为什么我添加#语言律师 tag。

  • 这个问题不是关于何时应该使用(),什么时候应该使用result<(),e>或这样。如您所知,可以在许多文档或教程中找到此类问题的答案(或至少提示或标准)。


更新:

终止特征最终在Rust 1.61.0中稳定( source )。

According to The Rust Reference,

If a main function is present, (snip), and its return type must be one of the following:

  • ()

  • Result<(), E> where E: Error

but it doesn't say what happens when main() returns (), Ok(()) or Err(<value>).

As far as I tested,

()Ok(())Err(<value>)
Exit Status001
Additional Behavior--Error: <value> is printed to stderr

Are these behaviors defined, explicitly explained or guaranteed in some documentation? In particular, can I assume

  • a program always exits with 1 status when main() returns Err(<value>)?

  • the error message displayed when main() returns Err(<value>) is always of the form Error: <value>?


Notes:

  • I want some sort of documented guarantee rather than an empirical explanation. This is why I added #language-lawyer tag.

  • This question is not about When should I use () and when should I use Result<(), E>? or such. One can find answers (or at least hints or criteria) to such questions in many documentations or tutorials, as you know.


Updates:

Termination trait is finally stabilized in Rust 1.61.0 (source).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

第七度阳光i 2025-02-01 03:30:59

来自main的不同返回值的行为由 std :: Process :: termination 特征:

特质std :: Process :: termination

在主函数中实现任意返回类型的特征。

记录了此特征以返回成功的libc :: exit_success在错误上libc :: exit_failure错误。

默认实现正在返回libc :: exit_success表示成功执行。如果发生故障,libc :: exit_failure将返回。

但是这些值不能保证在非 - 上为0和1 POSIX系统


至于打印错误消息,termination需要e:debug并确实打印debug insp to stderr,但我不相信它可以保证保持完全一样。

impl<E: fmt::Debug> Termination for Result<!, E> {
    fn report(self) -> ExitCode {
        let Err(err) = self;
        eprintln!("Error: {:?}", err);
        ExitCode::FAILURE.report()
    }
}

source

The behavior of different return values from main is defined by the std::process::Termination trait:

trait std::process::Termination

A trait for implementing arbitrary return types in the main function.

This trait is documented to return libc::EXIT_SUCCESS on success and libc::EXIT_FAILURE on error.

The default implementations are returning libc::EXIT_SUCCESS to indicate a successful execution. In case of a failure, libc::EXIT_FAILURE is returned.

But those values aren't guaranteed to be 0 and 1 on non-POSIX systems.


As for printing the error message, Termination requires E: Debug and does print the Debug impl to stderr, but I don't believe it's guaranteed to stay exactly the same.

impl<E: fmt::Debug> Termination for Result<!, E> {
    fn report(self) -> ExitCode {
        let Err(err) = self;
        eprintln!("Error: {:?}", err);
        ExitCode::FAILURE.report()
    }
}

Source

最好是你 2025-02-01 03:30:59

此行为由 std :: Process :: termination :: /code>特征,在 RFC 1937 。特别是,“隐藏” lang_start()函数 - 呼叫main() - 看起来大致喜欢:

fn lang_start<T: Termination>(
    main: fn() -> T,
    argc: isize,
    argv: *const *const u8
) -> !

main(Main()可以返回任何t:终止。有实现 >在std for ,(),std :: Process:exitCode和一些result&lt ; t,e&gt; -variants其中e:debug。这就是为什么您可以返回()ok(())以及其他来自main()的其他。

在您的问题上,语言律师模式:依赖终止的任何程序的确切行为并未由语言本身严格指定。它是std实现的一部分,而不是语言参考的一部分。这意味着与编译器不同版本的编译时,相同的程序可能会有所不同(与不同的std版本结合)。 err案例中打印错误的确切行为是 记录的 ,但未指定。正如RFC 1937明确寻找类似Posix的行为的那样,您可以合理地确保该程序不会以惊人的方式行事(例如,在ery - ery 中,具有状态 0 - 案件)。

This behavior is controlled by the std::process::Termination Trait, which was added in RFC 1937. In particular, the "hidden" lang_start() function - which calls main() - looks roughly like:

fn lang_start<T: Termination>(
    main: fn() -> T,
    argc: isize,
    argv: *const *const u8
) -> !

that is, main() can return any T: Termination. There are implementations of Termination in std for !, (), std::process:ExitCode, and some Result<T, E>-variants where E: Debug. This is why you can return (), Ok(()) and others from main().

To your question, language lawyer mode: The exact behavior of any program that relies on Termination is not strictly specified by the language itself. It is part of the std implementation, not part of the language reference. That means that the same program might behave differently when compiled with different versions of the compiler (binding to different std versions). The exact behavior for printing errors in the Err case is documented but not specified. As RFC 1937 explicitly looks for POSIX-like behavior, you can be reasonably assured that the program will not behave in wildly suprising ways (e.g. exit with status 0 in an Err-case).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文