Rust 新版解读 | 1.73 | panic 报错展示优化

Rust 1.73 官方 release doc: Announcing Rust 1.73.0 | Rust Blog

通过 rustup 安装的同学可以使用以下命令升级到 1.73 版本:

$ rustup update stable

更简洁的 panic 报错信息

默认的 panic handler 会把报错信息单独列出一行,当报错信息很长、包含多行或者嵌套结构的时候可读性会更强。

fn main() {
    let file = "ferris.txt";
    panic!("oh no! {file:?} not found!");
}

Rust 1.73 之前的:

thread 'main' panicked at 'oh no! "ferris.txt" not found!', src/main.rs:3:5

Rust 1.73 之后的:

thread 'main' panicked at src/main.rs:3:5:
oh no! "ferris.txt" not found!

另外,由 assert_eqassert_ne 产生的 panic 消息也把自定义信息部分(第三个参数)的展示位置改动了一下:

fn main() {
    assert_eq!("🦀", "🐟", "ferris is not a fish");
}

Rust 1.73 之前的:

thread 'main' panicked at 'assertion failed: `(left == right)`
 left: `"🦀"`,
right: `"🐟"`: ferris is not a fish', src/main.rs:2:5

Rust 1.73 之后的:

thread 'main' panicked at src/main.rs:2:5:
assertion `left == right` failed: ferris is not a fish
 left: "🦀"
right: "🐟"

线程局部初始化

RFC 3184 提案, LocalKey<Cell<T>>LocalKey<RefCell<T>> 现在可以直接用 get(), set(), take()replace() 方法来操作,不再需要写 with(|inner|...) 的闭包形式。声明线程静态局部变量的宏 thread_local! 内部就是使用的就是 LocalKey<T>

新的方法让代码更简洁,也避免了默认值在新线程运行额外的初始化代码。

#![allow(unused)]
fn main() {
thread_local! {
    static THINGS: Cell<Vec<i32>> = Cell::new(Vec::new());
}

fn f() {
    // before:
    THINGS.with(|i| i.set(vec![1, 2, 3]));
    // now:
    THINGS.set(vec![1, 2, 3]);

    // ...

    // before:
    let v = THINGS.with(|i| i.take());
    // now:
    let v: Vec<i32> = THINGS.take();
}
}

Others

其它更新细节,和稳定的API列表,参考原Blog