Rust 新版解读 | 1.61 | 重点: 自定义 main 函数 ExitCode、const fn 增强、为锁定的 stdio 提供静态句柄
原文链接: https://blog.rust-lang.org/2022/05/19/Rust-1.61.0.html 翻译 by :AllanDowney
通过 rustup 安装的同学可以使用以下命令升级到 1.61 版本:
$ rustup update stable
支持自定义 main 函数 ExitCode
一开始, Rust main
函数只能返回单元类型 ()
(隐式或显式),总是指示成功的退出状态,如果您要你想要其它的,必须调用 process::exit(code)
。从 Rust 1.26 开始, main
允许返回一个 Result
,其中 Ok
转换为 C EXIT_SUCCESS
,Err
转换为 EXIT_FAILURE
(也调试打印错误)。在底层,这些返回类型统一使用不稳定的 Termination
特征。
在此版本中,最终稳定了 Termination
特征,以及一个更通用的 ExitCode
类型,它封装了特定于平台的返回类型。它具有 SUCCESS
和 FAILURE
常量,并为更多任意值实现 From<u8>
。也可以为您自己的类型实现 Termination
特征,允许您在转换为 ExitCode
之前定制任何类型的报告。
例如,下面是一种类型安全的方式来编写 git bisect
运行脚本的退出代码:
use std::process::{ExitCode, Termination}; #[repr(u8)] pub enum GitBisectResult { Good = 0, Bad = 1, Skip = 125, Abort = 255, } impl Termination for GitBisectResult { fn report(self) -> ExitCode { // Maybe print a message here ExitCode::from(self as u8) } } fn main() -> GitBisectResult { std::panic::catch_unwind(|| { todo!("test the commit") }).unwrap_or(GitBisectResult::Abort) }
const fn 增强
这个版本稳定了几个增量特性,以支持 const 函数的更多功能:
fn
指针的基本处理:现在可以在const fn
中创建、传递和强制转换函数指针。例如,在为解释器构建编译时函数表时,这可能很有用。但是,仍然不允许调用fn
指针。- 特征约束:现在可以将特征约束写在
const fn
的泛型参数上,如T: Copy
,以前只允许Sized
。 dyn Trait
类型:类似地,const fn
现在可以处理特征对象dyn Trait
。impl Trait
类型:const fn
的参数和返回值现在可以是不透明的impl Trait
类型。
注意,特征特性还不支持在 const fn
中调用这些特征的方法。
为锁定的 stdio 提供静态句柄
三种标准 I/O 流 —— Stdin
、Stdout
和 Stderr
—— 都有一个 锁(&self)
,允许对同步读写进行更多控制。但是,它们返回的锁守卫具有从 &self
借来的生命周期,因此它们被限制在原始句柄的范围内。这被认为是一个不必要的限制,因为底层锁实际上是在静态存储中,所以现在守卫返回一个 'static
生命期,与句柄断开连接。
例如,一个常见的错误来自于试图获取一个句柄并将其锁定在一个语句中:
#![allow(unused)] fn main() { // error[E0716]: temporary value dropped while borrowed let out = std::io::stdout().lock(); // ^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement // | // creates a temporary which is freed while still in use }
现在锁守卫是 'static
,而不是借用那个临时的,所以这个可以正常工作!