如何从主函数外部提前退出 Rust 程序?
Posted
技术标签:
【中文标题】如何从主函数外部提前退出 Rust 程序?【英文标题】:How do I exit a Rust program early from outside the main function? 【发布时间】:2014-03-01 10:32:50 【问题描述】:我正在用 Rust 编写 bash
克隆。当用户键入exit
时,我需要退出我的程序。在我的程序之前的迭代中,在我添加更复杂的功能之前,我使用return
来退出提示用户输入的循环。这个逻辑现在在一个函数中,因为我实现内置 shell 函数的方式,所以当我 return
它只是跳出函数回到控制循环,而不是短路控制循环并结束程序。
我意识到当用户键入 exit
并退出循环时我可能会返回一个布尔值,但我至少想知道 Rust 是否有办法提前终止程序,类似于 Java 的 System.exit()
,如这对于某些类型的程序很有用。
【问题讨论】:
不,没有安全的方法可以提前终止 Rust 程序。使每项任务完全放松(返回或失败)是唯一的方法。 【参考方案1】:Rust 1.0 稳定版
std::process::exit()
正是这样做的——它使用指定的退出代码终止程序:
use std::process;
fn main()
for i in 0..10
if i == 5
process::exit(1);
println!("", i);
此函数会导致程序立即终止,而无需展开和运行析构函数,因此应谨慎使用。
替代(不推荐)解决方案
您可以直接使用 C API。将libc = "0.2"
添加到Cargo.toml
,并且:
fn main()
for i in 0..10
if i == 5
unsafe libc::exit(1);
println!("", i);
Rust 编译器无法验证调用 C 函数,因此这需要 unsafe
块。程序使用的资源不会被正确释放。这可能会导致诸如挂起套接字之类的问题。
据我了解,退出程序的正确方法是以某种方式终止所有线程,然后进程将自动退出。
【讨论】:
我试过了,效果很好。不过,如果有办法通过 Rust 而不是通过 C 库来做到这一点,那就太好了。谢谢! 使用libc::exit
是一个坏主意。它不会干净地终止该过程,并且可能会危险地破坏事情。正常的 Rust 进程结论必须涉及堆栈展开以便调用析构函数,而 exit(3)
的结论方法完全不同,不涉及堆栈展开。因此,如果您有诸如打开文件之类的东西,它们可能不会被刷新和关闭,TCP 绑定套接字可能无法正确释放(这意味着您无法绑定到套接字,直到超时到期,可能一分钟左右),&c。 —libc::exit
基本上相当于一个段错误,而不是一个干净的退出。
@ChrisMorgan,是的,我期待这样的事情。但我找不到其他方法。 Rust 是否提供了一种干净地终止当前任务而不会失败的方法?还是另一种停止该过程的方法?编辑:哦,对不起,没有看到你对这个问题的评论。真可惜……
@ChrisMorgan 套接字绑定由操作系统处理;一旦你退出,它就会清理干净。您可以立即重新绑定。不过,未刷新的文件缓冲区确实有效。
@VladimirMatveev 我在使用 exit() 时遇到编译错误,知道为什么吗? src\main.rs:14:27: 14:28 错误:预期类型,找到1
src\main.rs:14 std::process:exit(1);【参考方案2】:
panic!("Oh no something bad has happened!")
例子:
if a * g < 0f32 panic!("The arithmetric-geometric mean is undefined for numbers less than zero!");
在较旧的文档中,您会认为这是失败的!(“哦,这里没有发生任何不好的事情。”)
由于某种原因,此宏已从失败更改为恐慌。如果必须,恐慌是失败的方式。
[编辑] 对不起。看起来您应该测试字符串“exit”的输入,这取决于您如何接受输入(按行或按参数)。然后你可以让程序在检测到退出的情况下跳出循环。
例子:
loop
if exit_found break
else
// your thing, which also looks for exit_found
【讨论】:
请注意,panic!
所做的只是优雅地终止当前任务。如果该功能当前不在主要任务上,则panic!
不会exit
程序。即使是这样,它也与exit
不同,因为panic!
将使用任意代码运行析构函数。
失败!被重命名为恐慌!在这个 RFC 中:github.com/rust-lang/rfcs/blob/…以上是关于如何从主函数外部提前退出 Rust 程序?的主要内容,如果未能解决你的问题,请参考以下文章
2. 用一个函数来实现将一行字符串中最长的单词输出。此行字符从主函数传递给该函数。C语言高手快出现