Rust的新版本1.63.0的详细指南

331 阅读5分钟

Rust团队很高兴地宣布Rust的新版本,即1.63.0。Rust是一种编程语言,使每个人都能建立可靠和高效的软件。

如果你已经通过rustup安装了以前的Rust版本,你可以用1.63.0获得:

rustup update stable

如果你还没有,你可以从我们网站的相应页面获得rustup,并在GitHub上查看1.63.0的详细发布说明

如果你想通过测试未来的版本来帮助我们,你可以考虑在本地更新,使用测试频道(rustup default beta)或夜间频道(rustup default nightly)。请报告你可能遇到的任何错误!

1.63.0稳定版中的内容

作用域线程

从1.0开始,Rust的代码可以通过std::thread::spawn 来启动新的线程,但这个函数以'static 来限定其关闭。粗略地说,这意味着线程目前必须拥有传入其闭包的任何参数的所有权;你不能将借来的数据传入一个线程。在线程被期望在函数结束时退出的情况下(通过join()'d),这并不是严格必要的,可能需要一些变通方法,比如将数据放在一个 Arc.

现在,在1.63.0版本中,标准库增加了作用域线程,它允许从本地堆栈帧中借出线程。该std::thread::scopeAPI提供了必要的保证,即任何生成的线程都会在其返回之前退出,这使得安全地借用数据成为可能。这里有一个例子:

let mut a = vec![1, 2, 3];
let mut x = 0;

std::thread::scope(|s| {
    s.spawn(|| {
        println!("hello from the first scoped thread");
        // We can borrow `a` here.
        dbg!(&a);
    });
    s.spawn(|| {
        println!("hello from the second scoped thread");
        // We can even mutably borrow `x` here,
        // because no other threads are using it.
        x += a[0] + a[2];
    });
    println!("hello from the main thread");
});

// After the scope, we can modify and access our variables again:
a.push(4);
assert_eq!(x, a.len());

Rust对原始文件描述符/句柄的所有权(I/O安全)

以前,Rust代码在使用平台API时,如果使用原始文件描述符(在unix风格的平台上)或句柄(在Windows上),通常会直接使用描述符的平台特定表示(例如,c_int ,或别名RawFd )。对于Rust与此类本地API的绑定,类型系统就无法编码API是否会取得文件描述符的所有权(例如,close )或仅仅借用它(例如,dup )。

现在,Rust提供了一些封装类型,如 BorrowedFdOwnedFd,它们被标记为#[repr(transparent)] ,这意味着extern "C" 绑定可以直接使用这些类型来编码所有权语义。关于1.63中稳定的包装器类型的完整列表,请参见稳定的API部分,目前,它们在cfg(unix)平台、Windows和WASI上可用。

我们建议新的API使用这些类型而不是以前的类型别名(如 RawFd).

const Mutex、RwLock、Condvar初始化

Condvar::new, Mutex::new,和 RwLock::new函数现在可以在const 上下文中调用,这样就可以避免使用lazy_static 这样的板块来创建带有MutexRwLockCondvar值的全局状态。这建立在1.62的工作基础上,以便在Linux上实现更薄更快的mutexes。

涡轮鱼用于函数中的泛型,具有impl Trait

对于像fn foo<T>(value: T, f: impl Copy) 这样的函数签名,通过turbofish指定T 的具体类型是一个错误。foo::<u32>(3, 3) 将会以失败告终:

error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position
 --> src/lib.rs:4:11
  |
4 |     foo::<u32>(3, 3);
  |           ^^^ explicit generic argument not allowed
  |
  = note: see issue #83701 <https://github.com/rust-lang/rust/issues/83701> for more information

在1.63中,这个限制被放宽了,泛型的显式类型可以被指定。然而,impl Trait 参数,尽管被解构为一个泛型,仍然是不透明的,不能通过turbofish指定。

非逻辑寿命的迁移完成

正如这篇博文中所详述的,我们已经从所有版本的rustc中完全删除了之前的词法借用检查器,完全启用了非词法的、新版本的借用检查器。由于借贷检查器不影响rustc的输出,这不会改变任何程序的行为,但它完成了一个长期的迁移(从2018年版本的NLL的初始稳定开始),在所有版本的Rust中提供新的借贷检查器的全部好处。对于大多数用户来说,这一变化将为一些借款检查错误带来略微更好的诊断,但在其他方面不会影响他们可以编写哪些代码。

你可以在2018版公告的这一节中阅读更多关于非逻辑寿命的内容。

稳定的API

以下方法和特质的实现现在已经稳定了:

这些API现在可以在const语境中使用:

其他变化

在Rust 1.63.0版本中还有其他变化,请查看RustCargoClippy中的变化。

1.63.0的贡献者

许多人共同创造了Rust 1.63.0,没有你们,我们不可能做到这一点,谢谢!"。