Rust 1.80.0 稳定版现已发布,主要带来以下变化:

LazyCellLazyLock

新的“lazy”类型将值的初始化延迟到首次访问,它们类似于1.70 中稳定的OnceCellOnceLock类型,但单元格中包含了初始化函数。这完成了从流行的和板条箱中采用到标准库中的功能的稳定化。完成了从lazy_staticonce_cellcrates 到标准库中所采用功能的稳定化。

LazyLock 是线程安全选项,适用于static values 等地方。

use std::sync::LazyLock;use std::time::Instant;static LAZY_TIME: LazyLock<Instant> = LazyLock::new(Instant::now);fn main() {    let start = Instant::now();    std::thread::scope(|s| {        s.spawn(|| {            println!("Thread lazy time is {:?}", LAZY_TIME.duration_since(start));        });        println!("Main lazy time is {:?}", LAZY_TIME.duration_since(start));    });}

LazyCell 缺乏线程同步,因此没有实现static所需的 Sync,但仍可用于thread_local! statics。Rust团队表示,根据线程安全的需要,这两种类型也可用于其他数据结构,因此 lazy initialization 在任何地方都可用。

Checked cfg names and values

在 1.79 中,rustc稳定了一个--check-cfgflag,现在 Cargo 1.80 正在对其知道的所有cfg名称和值启用这些检查(除了来自rustc众所周知的名称和值)。包括来自Cargo.toml的功能名称以及来自构建脚本的新cargo::rustc-check-cfgoutput。

unexpected_cfgs会被 warning-by-default unexpected_cfgs lint 报告,用于捕获拼写错误或其他错误配置。例如,在具有可选rayon依赖项的项目中,此代码配置了错误的feature值:

fn main() {    println!("Hello, world!");    #[cfg(feature = "crayon")]    rayon::join(        || println!("Hello, Thing One!"),        || println!("Hello, Thing Two!"),    );}
warning: unexpected `cfg` condition value: `crayon` --> src/main.rs:4:11  |4 |     #[cfg(feature = "crayon")]  |           ^^^^^^^^^^--------  |                     |  |                     help: there is a expected value with a similar name: `"rayon"`  |  = note: expected values for `feature` are: `rayon`  = help: consider adding `crayon` as a feature in `Cargo.toml`  = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration  = note: `#[warn(unexpected_cfgs)]` on by default

无论实际的rayon功能是否启用,都会报告相同的警告。

还可以使用Cargo.toml清单中的[lints]表来扩展自定义cfg的已知名称和值列表。rustc会自动提供警告中使用的语法。

[lints.rust]unexpected_cfgs = { level = "warn", check-cfg = ['cfg(foo, values("bar"))'] }

可以在之前的博客文章中阅读有关此功能的更多信息。

Exclusive ranges in patterns

Rust ranged 模式现在可以使用 exclusive endpoints,写成a..b..b,类似于Range 和 RangeTo表达式类型。例如,以下模式现在可以在一个模式的终点和下一个模式的起点使用相同的常量:

pub fn size_prefix(n: u32) -> &'static str {    const K: u32 = 10u32.pow(3);    const M: u32 = 10u32.pow(6);    const G: u32 = 10u32.pow(9);    match n {        ..K => "",        K..M => "k",        M..G => "M",        G.. => "G",    }}

Exclusive ranges 一直以来作为一个不稳定的功能提供。Rust 团队表示,阻碍因素在于它们可能会增加混乱并增加模式中出现 off-by-one errors 的可能性。在 Rust 1.80 中,exhaustiveness checking 得到了增强,可以更好地检测模式匹配中的差距,新的 lintnon_contiguous_range_endpointsoverlapping_range_endpoints将有助于检测在哪些情况下需要将 exclusive 模式切换为 inclusive 模式,反之亦然。

Rust 1.80 还稳定了许多 API,详情可查看官方公告

免责声明:本文系转载,版权归原作者所有;旨在传递信息,不代表一休教程网的观点和立场。