You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
4.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Rust 新版解读 | 1.87 | 十周年🎉
[Rust 1.0](https://blog.rust-lang.org/2015/05/15/Rust-1.0/) 十周年🎉
> Rust 1.87 官方 release doc: [Announcing Rust 1.87.0 | Rust Blog](https://blog.rust-lang.org/2025/05/15/Rust-1.87.0/)
通过 [rustup](https://www.rust-lang.org/tools/install) 安装的同学可以使用以下命令升级到 1.87 版本:
```shell
$ rustup update stable
```
## 匿名管道
1.87 版本为标准库添加了匿名管道支持,包括与 `std::process::Command` 输入/输出方法的集成。例如,现在可以相对简单地合并标准输出和标准错误流,如下所示,而过去需要额外线程或平台特定函数才能实现。
```rust
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` 内置函数,现在可以在已启用相应特性的安全代码中调用。例如,以下使用手动内置函数实现数组求和的示例程序,现在核心循环可以使用安全代码。
```rust
#![forbid(unsafe_op_in_unsafe_fn)]
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](https://github.com/rust-lang/rust/issues/119364)的
```rust
unsafe {
asm!(
"jmp {}",
label {
println!("从汇编跳转而来!");
}
);
}
```
更多细节请参阅[参考文档](https://doc.rust-lang.org/nightly/reference/inline-assembly.html#r-asm.operand-type.supported-operands.label)。
## 特征定义中 `impl Trait` 的精确捕获 (`+ use<...>`)
本版本稳定了在特征定义中使用 `impl Trait` 返回类型时指定具体捕获的泛型类型和生命周期的功能。这扩展了 [1.82](https://blog.rust-lang.org/2024/10/17/Rust-1.82.0/#precise-capturing-use-syntax) 版本中对非特征函数的稳定支持。
一些示例解语法:
```rust
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](https://blog.rust-lang.org/2025/05/15/Rust-1.87.0/#stabilized-apis)