Rust 新版解读 | 1.87 | 十周年🎉
Rust 1.0 十周年🎉
Rust 1.87 官方 release doc: Announcing Rust 1.87.0 | Rust Blog
通过 rustup 安装的同学可以使用以下命令升级到 1.87 版本:
$ rustup update stable
匿名管道
1.87 版本为标准库添加了匿名管道支持,包括与 std::process::Command
输入/输出方法的集成。例如,现在可以相对简单地合并标准输出和标准错误流,如下所示,而过去需要额外线程或平台特定函数才能实现。
#![allow(unused)] fn main() { use std::process::Command; use std::io::Read; let (mut recv, send) = std::io::pipe()?; let mut command = Command::new("path/to/bin") // 标准输出和标准错误都会写入同一个管道,实现合并 .stdout(send.try_clone()?) .stderr(send) .spawn()?; let mut output = Vec::new(); recv.read_to_end(&mut output)?; // 必须在进程退出前读取管道内容,避免程序输出过多时填满系统缓冲区 assert!(command.wait()?.success()); }
安全的架构内置函数
大多数仅因需要启用目标特性而被标记为不安全的 std::arch
内置函数,现在可以在已启用相应特性的安全代码中调用。例如,以下使用手动内置函数实现数组求和的示例程序,现在核心循环可以使用安全代码。
#![allow(unused)] #![forbid(unsafe_op_in_unsafe_fn)] fn main() { use std::arch::x86_64::*; fn sum(slice: &[u32]) -> u32 { #[cfg(target_arch = "x86_64")] { if is_x86_feature_detected!("avx2") { // 安全性:我们已检测到运行时启用了该特性,因此调用此函数是安全的 return unsafe { sum_avx2(slice) }; } } slice.iter().sum() } #[target_feature(enable = "avx2")] #[cfg(target_arch = "x86_64")] fn sum_avx2(slice: &[u32]) -> u32 { // 安全性:__m256i 和 u32 具有相同的有效性 let (prefix, middle, tail) = unsafe { slice.align_to::<__m256i>() }; let mut sum = prefix.iter().sum::<u32>(); sum += tail.iter().sum::<u32>(); // 在 1.87 中核心循环现在是完全安全的代码,因为内置函数要求与函数定义匹配的目标特性 (avx2) let mut base = _mm256_setzero_si256(); for e in middle.iter() { base = _mm256_add_epi32(base, *e); } // 安全性:__m256i 和 u32 具有相同的有效性 let base: [u32; 8] = unsafe { std::mem::transmute(base) }; sum += base.iter().sum::<u32>(); sum } }
asm!
跳转到 Rust 代码
内联汇编 (asm!
) 现在可以跳转到 Rust 代码中的 labeled 代码块。这为底层编程提供了更大灵活性,例如在操作系统内核中实现优化控制流,或更高效地与硬件交互。
asm!
宏现在支持 label 标签语法,作为跳转目标- label 必须是返回类型为
()
或!
的块表达式 - 跳转时会执行该块,然后继续执行
asm!
块之后的代码 - 在同一
asm!
里使用调用中使用 output 和 label 仍处于unstable的
#![allow(unused)] fn main() { unsafe { asm!( "jmp {}", label { println!("从汇编跳转而来!"); } ); } }
更多细节请参阅参考文档。
特征定义中 impl Trait
的精确捕获 (+ use<...>
)
本版本稳定了在特征定义中使用 impl Trait
返回类型时指定具体捕获的泛型类型和生命周期的功能。这扩展了 1.82 版本中对非特征函数的稳定支持。
一些示例解语法:
#![allow(unused)] fn main() { trait Foo { fn method<'a>(&'a self) -> impl Sized; // ... 解语法后类似: type Implicit1<'a>: Sized; fn method_desugared<'a>(&'a self) -> Self::Implicit1<'a>; // ... 而使用精确捕获时 ... fn precise<'a>(&'a self) -> impl Sized + use<Self>; // ... 解语法后类似: type Implicit2: Sized; fn precise_desugared<'a>(&'a self) -> Self::Implicit2; } }
Others
其它更新细节,和稳定的 API 列表,参考原Blog