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 安全性)
以前,使用接受原始文件描述符(在类 Unix 平台上)或句柄(在 Windows 上)的平台 API 的 Rust 代码通常会直接使用描述符的平台特定表示形式(例如,c_int
或别名 RawFd
)。 对于此类原生 API 的 Rust 绑定,类型系统无法编码 API 是会取得文件描述符的所有权(例如,close
)还是仅借用它(例如,dup
)。
现在,Rust 提供了诸如 BorrowedFd
和 OwnedFd
之类的包装类型,这些类型被标记为 #[repr(transparent)]
,这意味着 extern "C"
绑定可以直接使用这些类型来编码所有权语义。 请参阅稳定的 API 部分,了解在 1.63 中稳定的完整包装类型列表,目前它们在 cfg(unix) 平台、Windows 和 WASI 上可用。
我们建议新的 API 使用这些类型,而不是之前的类型别名(例如 RawFd
)。
const
Mutex、RwLock、Condvar 初始化
现在可以在 const
上下文中调用 Condvar::new
、Mutex::new
和 RwLock::new
函数,这允许避免使用诸如 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_fn
Box::into_pin
BinaryHeap::try_reserve
BinaryHeap::try_reserve_exact
OsString::try_reserve
OsString::try_reserve_exact
PathBuf::try_reserve
PathBuf::try_reserve_exact
Path::try_exists
Ref::filter_map
RefMut::filter_map
NonNull::<[T]>::len
ToOwned::clone_into
Ipv6Addr::to_ipv4_mapped
unix::io::AsFd
unix::io::BorrowedFd<'fd>
unix::io::OwnedFd
windows::io::AsHandle
windows::io::BorrowedHandle<'handle>
windows::io::OwnedHandle
windows::io::HandleOrInvalid
windows::io::HandleOrNull
windows::io::InvalidHandleError
windows::io::NullHandleError
windows::io::AsSocket
windows::io::BorrowedSocket<'handle>
windows::io::OwnedSocket
thread::scope
thread::Scope
thread::ScopedJoinHandle
这些 API 现在可以在 const 上下文中使用
array::from_ref
slice::from_ref
intrinsics::copy
intrinsics::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_nonoverlapping
str::from_utf8
Utf8Error::error_len
Utf8Error::valid_up_to
Condvar::new
Mutex::new
RwLock::new
其他更改
Rust 1.63.0 版本还有其他更改。查看 Rust、Cargo 和 Clippy 中更改的内容。
1.63.0 的贡献者
很多人齐心协力创建了 Rust 1.63.0。 没有你们所有人,我们不可能做到这一点。 谢谢!