Rust 团队很高兴地宣布 Rust 的新版本 1.42.0。Rust 是一种编程语言,它正在赋能每个人构建可靠且高效的软件。
如果你之前通过 rustup 安装了 Rust 版本,那么获取 Rust 1.42.0 非常简单,只需运行:
$ rustup update stable
如果你还没有安装 rustup,你可以从我们网站的相应页面获取 rustup
,并查看 GitHub 上1.42.0 的详细发行说明。
1.42.0 稳定版的新特性
Rust 1.42.0 的亮点包括:在 unwrap
时提供更有用的 panic 消息、子切片模式、弃用 Error::description
等。请参阅详细发行说明,了解本文未涵盖的其他更改。
Option
和 Result
的 panic 消息中提供有用的行号
在 在 Rust 1.41.1 中,在 Option::None
值上调用 unwrap()
会产生如下错误消息:
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', /.../src/libcore/macros/mod.rs:15:40
类似地,由 unwrap_err
、expect
和 expect_err
以及 Result
类型上的相应方法生成的 panic 消息中的行号,也指向 core
的内部。
在 Rust 1.42.0 中,所有这八个函数都会生成 panic 消息,其中提供调用它们的行号。新的错误消息如下所示:
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/main.rs:2:5
这意味着对 unwrap
的无效调用是在 src/main.rs
的第 2 行进行的。
此行为由一个注解 #[track_caller]
实现。此注解尚不能在稳定的 Rust 中使用;如果你有兴趣在自己的代码中使用它,你可以通过关注此跟踪问题来了解其进展。
子切片模式
在 Rust 1.26 中,我们稳定了“切片模式”,允许你在切片上进行 match
匹配。它们看起来像这样:
fn foo(words: &[&str]) {
match words {
[] => println!("empty slice!"),
[one] => println!("one element: {:?}", one),
[one, two] => println!("two elements: {:?} {:?}", one, two),
_ => println!("I'm not sure how many elements!"),
}
}
这允许你在切片上进行匹配,但相当有限。你必须选择你希望支持的确切大小,并且必须为你不希望支持的大小设置一个兜底分支。
在 Rust 1.42 中,我们扩展了对切片部分匹配的支持:
fn foo(words: &[&str]) {
match words {
["Hello", "World", "!", ..] => println!("Hello World!"),
["Foo", "Bar", ..] => println!("Baz"),
rest => println!("{:?}", rest),
}
}
..
称为“剩余模式”,因为它匹配切片的其余部分。上面的示例在切片的末尾使用了剩余模式,但你也可以以其他方式使用它:
fn foo(words: &[&str]) {
match words {
// Ignore everything but the last element, which must be "!".
[.., "!"] => println!("!!!"),
// `start` is a slice of everything except the last element, which must be "z".
[start @ .., "z"] => println!("starts with: {:?}", start),
// `end` is a slice of everything but the first element, which must be "a".
["a", end @ ..] => println!("ends with: {:?}", end),
rest => println!("{:?}", rest),
}
}
如果你有兴趣了解更多信息,我们在 Inside Rust 博客上发表了一篇文章,讨论了这些更改以及我们未来可能引入稳定版的更多模式匹配改进!你也可以在Thomas Hartmann 的文章中阅读更多关于切片模式的信息。
matches!
此版本的 Rust 稳定了一个新的宏,matches!
。此宏接受一个表达式和一个模式,如果该模式与表达式匹配,则返回 true。换句话说:
// Using a match expression:
match self.partial_cmp(other) {
Some(Less) => true,
_ => false,
}
// Using the `matches!` macro:
matches!(self.partial_cmp(other), Some(Less))
你还可以使用诸如 |
模式和 if
守卫之类的功能:
let foo = 'f';
assert!(matches!(foo, 'A'..='Z' | 'a'..='z'));
let bar = Some(4);
assert!(matches!(bar, Some(x) if x > 2));
use proc_macro::TokenStream;
现在可以使用了
在 Rust 2018 中,我们取消了对 extern crate
的需求。但是过程宏有点特殊,因此在编写过程宏时,你仍然需要声明 extern crate proc_macro;
。
在此版本中,如果你正在使用 Cargo,在使用 2018 版时,你不再需要这一行;你可以像使用任何其他 crate 一样使用 use
。鉴于大多数项目已经有类似于 use proc_macro::TokenStream;
的行,此更改将意味着你可以删除 extern crate proc_macro;
行,并且你的代码仍然可以工作。此更改很小,但使过程宏更接近常规代码。
库
iter::Empty<T>
现在为任何T
实现Send
和Sync
。Pin::{map_unchecked, map_unchecked_mut}
不再要求返回类型实现Sized
。io::Cursor
现在实现PartialEq
和Eq
。Layout::new
现在是const
。
稳定的 API
CondVar::wait_while
&CondVar::wait_timeout_while
DebugMap::key
&DebugMap::value
ManuallyDrop::take
ptr::slice_from_raw_parts_mut
&ptr::slice_from_raw_parts
其他更改
Rust 1.42.0 版本还有其他更改:查看 Rust、Cargo 和 Clippy 中的更改。
兼容性说明
此版本有两个值得注意的兼容性说明:标准库中的一个弃用以及将 32 位 Apple 目标降级为 Tier 3。
Error::Description 已弃用
有时会犯错误。现在 Error::description
方法被认为是这些错误之一。问题在于它的类型签名:
fn description(&self) -> &str
因为 description
返回 &str
,它不像我们希望的那样有用。这意味着你基本上需要逐字返回 Error
的内容;如果你想说,使用格式化来产生更漂亮的描述,这是不可能的:你需要返回一个 String
。相反,错误类型应该实现 Display
/Debug
特性来提供错误的描述。
此 API 自 Rust 1.0 以来就存在。我们为此目标努力了很长时间:早在 Rust 1.27 中,我们就“软弃用”了此方法。这在实践中意味着,我们为该函数提供了默认实现。这意味着用户在实现 Error
特性时不再被迫实现此方法。在此版本中,我们将其标记为实际弃用,并采取了一些步骤来降低该方法在 Error
文档中的重要性。由于我们的稳定性策略,description
永远不会被删除,因此这是我们能做的最远一步。
降级 32 位 Apple 目标
Apple 不再支持 32 位目标,因此我们也不再支持。该项目已将其降级为 Tier 3 支持。有关此的更多详细信息,请查看 1 月份的这篇文章,其中详细介绍了所有内容。
1.42.0 的贡献者
很多人齐心协力创建了 Rust 1.42.0。没有你们所有人,我们不可能做到。 谢谢!