Rust 团队很高兴地宣布 Rust 新版本 1.63.0 发布。Rust 是一种旨在帮助每个人构建可靠且高效软件的编程语言。
如果您之前通过 rustup 安装了 Rust,您可以使用以下命令获取 1.63.0 版本:
$ rustup update stable
如果您尚未安装,您可以从我们的网站上的相应页面获取 rustup,并查看 GitHub 上 1.63.0 版本的详细发布说明。
如果您想通过测试未来的版本来帮助我们,您可以考虑将本地更新为 beta 频道 (rustup default beta) 或 nightly 频道 (rustup default nightly)。请报告您可能遇到的任何错误!
1.63.0 稳定版的新特性
作用域线程
自 1.0 版本以来,Rust 代码可以使用 std::thread::spawn 启动新线程,但此函数使用 'static 限定了其闭包。粗略地说,这意味着线程当前必须拥有传递到其闭包中的任何参数的所有权;您不能将借用的数据传递到线程中。在预期线程在函数结束前退出(通过 join())的情况下,这并非绝对必要,并且可能需要诸如将数据放置在 Arc 中的变通方法。
现在,在 1.63.0 版本中,标准库添加了作用域线程,允许生成一个线程从本地堆栈帧借用数据。std::thread::scope API 提供了必要的保证,即任何生成的线程都将在自身返回之前退出,从而允许安全地借用数据。这是一个例子:
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 安全)
以前,使用平台 API(在类 Unix 平台上)或句柄(在 Windows 上)的 Rust 代码通常会直接使用描述符的平台特定表示形式(例如,c_int 或别名 RawFd)。对于此类原生 API 的 Rust 绑定,类型系统随后无法编码 API 是会取得文件描述符的所有权(例如,close)还是仅仅借用它(例如,dup)。
现在,Rust 提供了包装器类型,例如 BorrowedFd 和 OwnedFd,它们被标记为 #[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 这样的 crate 来创建具有 Mutex、RwLock 或 Condvar 值的全局静态变量。这建立在 1.62 版本中 启用 Linux 上更薄更快的互斥锁的工作之上。
在带有 impl Trait 的函数中使用 turbofish 调用泛型
对于像 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
以下方法和 trait 实现现在已稳定:
array::from_fnBox::into_pinBinaryHeap::try_reserveBinaryHeap::try_reserve_exactOsString::try_reserveOsString::try_reserve_exactPathBuf::try_reservePathBuf::try_reserve_exactPath::try_existsRef::filter_mapRefMut::filter_mapNonNull::<[T]>::lenToOwned::clone_intoIpv6Addr::to_ipv4_mappedunix::io::AsFdunix::io::BorrowedFd<'fd>unix::io::OwnedFdwindows::io::AsHandlewindows::io::BorrowedHandle<'handle>windows::io::OwnedHandlewindows::io::HandleOrInvalidwindows::io::HandleOrNullwindows::io::InvalidHandleErrorwindows::io::NullHandleErrorwindows::io::AsSocketwindows::io::BorrowedSocket<'handle>windows::io::OwnedSocketthread::scopethread::Scopethread::ScopedJoinHandle
这些 API 现在可以在 const 上下文中使用:
array::from_refslice::from_refintrinsics::copyintrinsics::copy_nonoverlapping<*const T>::copy_to<*const T>::copy_to_nonoverlapping<*mut T>::copy_to<*mut T>::copy_to_nonoverlapping<*mut T>::copy_from<*mut T>::copy_from_nonoverlappingstr::from_utf8Utf8Error::error_lenUtf8Error::valid_up_toCondvar::newMutex::newRwLock::new
其他更改
Rust 1.63.0 版本中还有其他更改。查看 Rust、Cargo 和 Clippy 中的更改。
1.63.0 版本的贡献者
许多人共同努力创建了 Rust 1.63.0。没有你们所有人,我们不可能做到。谢谢!