皇上,还记得我吗?我就是1999年那个Linux伊甸园啊-----24小时滚动更新开源资讯,全年无休!

Rust 1.51.0 发布

Rust团队很高兴宣布一个新的Rust版本1.51.0。Rust是一种编程语言,它使每个人都可以构建可靠且高效的软件。

如果您通过rustup安装了旧版本的Rust,那么获取Rust 1.51.0就像下面这样简单:

rustup update stable

如果您还没有它,可以 从我们网站上的相应页面获取rustup,然后在GitHub上查看1.51.0的 详细发行说明

1.51.0稳定版中的内容

此版本代表了相当长一段时间以来Rust语言和Cargo的最大新增功能之一,稳定了const泛型的MVP和Cargo的新功能解析器。让我们开始吧!

Const Generics MVP

在此版本之前,Rust允许您在整个生命周期或类型中对类型进行参数化。例如,如果我们希望在struct数组的元素类型上具有通用的,则可以编写以下代码:

struct FixedArray<T> {
              // ^^^ Type generic definition
    list: [T; 32]
        // ^ Where we're using it.
}

如果再使用FixedArray<u8>,编译器将使它成为单态版本FixedArray,如下所示:

struct FixedArray<u8> {
    list: [u8; 32]
}

这是一项强大的功能,可让您编写可重用的代码,而没有运行时的开销。但是,直到发布此版本之前,不可能轻易地对这些类型的进行泛型。这在包含其长度的类型定义([T; N])中的数组中最为明显,以前您无法对其进行泛型。现在有了1.51.0,您可以编写对任何整数bool,或char类型的值通用的代码!(使用structenum值仍然不稳定。)

现在,此更改使我们可以拥有自己的数组结构,该数组结构在其类型长度上是通用的。让我们看一个示例定义,以及如何使用它。

struct Array<T, const LENGTH: usize> {
    //          ^^^^^^^^^^^^^^^^^^^ Const generic definition.
    list: [T; LENGTH]
    //        ^^^^^^ We use it here.
}

现在,如果再使用Array<u8, 32>,编译器将使它变为单态版本Array,如下所示:

struct Array<u8, 32> {
    list: [u8; 32]
}

Const泛型为库设计人员添加了一个重要的新工具,可用于创建功能强大的新编译时安全API。如果您想了解有关const泛型的更多信息,还可以查看“ Const Generics MVP Hits Beta”博客文章,以获取有关该功能及其当前限制的更多信息。我们迫不及待想看看您创建了哪些新的库和API!

array::IntoIter 稳定化

作为const泛型稳定化的一部分,我们还正在稳定使用它的新API std::array::IntoIterIntoIter允许您在任何数组上创建按值迭代器。以前,没有一种便捷的方法可以遍历数组的所有值,仅引用它们即可。

fn main() {
  let array = [1, 2, 3, 4, 5];
  
  // Previously
  for item in array.iter().copied() {
      println!("{}", item);
  }
  
  // Now
  for item in std::array::IntoIter::new(array) {
      println!("{}", item);
  }
}

注意,这是作为一个单独的方法而不是.into_iter()在数组上添加的,因为当前会引入一些破损。当前.into_iter()引用切片按引用迭代器。我们正在探索将来使之更符合人体工程学的方法。

货运的新功能解析器

依赖管理是一个难题,它最难的部分之一就是选择当两个不同的程序包依赖哪个版本的依赖时。这不仅包括其版本号,还包括该软件包启用或未启用的功能。Cargo的默认行为是在依赖关系图中多次引用单个包时合并功能。

例如,假设您有一个foo具有功能A和B的依赖项,该依赖项已由软件包bar和使用baz,但bar依赖于foo+Abaz依赖于foo+B。Cargo将合并这两个功能并将其编译foofoo+AB。这样的好处是您只需要编译foo一次,然后就可以为bar和重复使用baz

但是,这也有不利的一面。如果在构建依赖性中启用的功能与要构建的目标不兼容怎么办?

生态系统中一个常见的例子是std许多#![no_std]板条箱中包含的可选功能,允许板条箱在std可用时提供附加功能。现在,假设您要在二进制文件中使用的#![no_std]版本,并在中使用构建时的。如果您的构建时间依赖项依赖于,那么您的二进制文件现在也还依赖于,这意味着它将不再编译,因为它不适用于您的目标平台。foo#![no_std]foobuild.rsfoo+stdfoo+stdstd

这一直是货运中的一个长期问题,在此版本resolver中,您的中有一个新选项Cargo.toml,您可以在其中设置resolver="2"告诉货运尝试使用新方法来解析功能。您可以查看RFC 2957,以获得有关行为的详细说明,可以将其概述如下。

  • 开发依赖项—当程序包作为常规依赖项和开发依赖项共享时,仅当当前构建包含开发依赖项时,才启用开发依赖项功能。
  • 主机依赖关系—当程序包作为常规依赖关系和构建依赖关系或proc-macro共享时,用于常规依赖关系的功能将保持独立于构建依赖关系或proc-macro。
  • 目标依赖项—当程序包在构建图中多次出现,并且其中一个实例是特定于目标的依赖项时,仅当当前正在构建目标时,才启用特定于目标的依赖项的功能。

尽管这可能导致某些板条箱不止一次被编译,但是在将特征与货物一起使用时,这应该提供更直观的开发体验。如果您想了解更多信息,还可以阅读货运手册》中“功能解析器”部分以获取更多信息。我们要感谢货运团队以及所有参与设计和实施新分解器的辛勤工作的人!

[package]
resolver = "2"
# Or if you're using a workspace
[workspace]
resolver = "2"

拆分调试信息

尽管在发行版中并不经常强调,但Rust团队一直在努力改善Rust的编译时间,而该发行版是macOS上Rust长期以来最大的改进之一。调试信息将二进制代码映射回您的源代码,以便该程序可以为您提供有关运行时出现问题的更多信息。在macOS中,以前.dSYM使用名为的工具将调试信息收集到一个文件夹中,该工具dsymutil可能会花费一些时间并占用大量磁盘空间。

将所有debuginfo收集到此目录中有助于在运行时查找它,尤其是在二进制文件正在移动的情况下。但是,这样做的缺点是,即使您对程序进行了很小的更改,dsymutil也将需要在整个最终二进制.dSYM文件上运行以产生最终文件夹。有时这可能会增加构建时间,尤其是对于大型项目,因为总是会收集所有依赖项,但这是必需的步骤,因为如果没有它,Rust的标准库将不知道如何在macOS上加载调试信息。

最近,Rust回溯切换到使用其他后端,该后端支持无需运行即可加载debuginfo dsymutil,并且我们已稳定了对跳过dsymutil运行的支持。这可以显着加快包含debuginfo的构建,并显着减少所使用的磁盘空间量。我们还没有运行广泛的基准测试,但是已经看到很多关于人们使用这种行为在macOS上构建速度更快的报告。

您可以通过-Csplit-debuginfo=unpacked在运行时设置标志rustc或在Cargo中将选项设置为来启用此新行为。“解压”选项指示rustc将.o对象文件保留在生成输出目录中,而不是删除它们,并跳过运行dsymutil的步骤。Rust的回溯支持足够聪明,足以知道如何查找这些.o文件。诸如lldb之类的工具也知道如何执行此操作。只要您不需要在保留调试信息的情况下将二进制文件移动到其他位置,这就应该起作用。split-debuginfo [profile]unpacked

[profile.dev]
split-debuginfo = "unpacked"

稳定的API

总体而言,此发行版稳定了18种针对诸如slice和的各种类型的新方法的使用Peekable。一个显着的增加是稳定ptr::addr_of!ptr::addr_of_mut!,它允许您创建未对齐的领域原始指针。以前这是不可能的,因为Rust需要&/&mut对齐并指向初始化的数据,&addr as *const _然后由于&addr需要对齐会导致未定义的行为。这两个宏现在使您可以安全地创建未对齐的指针。

use std::ptr;

#[repr(packed)]
struct Packed {
    f1: u8,
    f2: u16,
}

let packed = Packed { f1: 1, f2: 2 };
// `&packed.f2` would create an unaligned reference, and thus be Undefined Behavior!
let raw_f2 = ptr::addr_of!(packed.f2);
assert_eq!(unsafe { raw_f2.read_unaligned() }, 2);

稳定了以下方法。

其他变化

Rust 1.51.0发行版中还有其他更改:查看RustCargoClippy中的更改。

1.51.0的贡献者

许多人一起创建了Rust 1.51.0。没有你们所有人,我们不可能做到这一点。谢谢!

机翻自 https://blog.rust-lang.org/2021/03/25/Rust-1.51.0.html