Rust 团队很高兴地宣布 Rust 的最新版本 1.13.0。Rust 是一门专注于安全性、速度和并发性的系统编程语言。
像往常一样,您可以从我们网站的相应页面安装 Rust 1.13.0,并查看 GitHub 上1.13.0 的详细发行说明。此版本中提交了 1448 个补丁。
Rust 的这个季度非常忙碌。我们连续举办了三个 Rust 会议,RustConf、RustFest 和 Rust Belt Rust。很高兴见到这么多 Rust 爱好者,其中一些人是第一次见面!我们一直在深入思考未来,制定了2017 年的路线图,并构建我们的用户告诉我们他们需要的工具。
即使发生了这么多事情,我们还是推出了一个充满有趣新功能的新版本。
1.13 稳定版中的新功能
1.13 版本包含语言的几个扩展,包括期待已久的 ?
运算符、编译时间的改进、cargo 和标准库的次要功能添加。此版本还包含了许多贡献者对文档和错误报告的许多小改进,这些改进没有在发行说明中单独提及。
此版本包含 Cargo 的重要安全更新,Cargo 依赖于 curl 和 OpenSSL,它们最近都发布了安全更新。有关更多信息,请参阅 curl 7.51.0 和 OpenSSL 1.0.2j 的相关公告。
?
运算符
Rust 获得了一个新的运算符 ?
,通过减少视觉噪音,使错误处理更加愉快。它通过解决一个简单的问题来实现这一点。为了说明这一点,假设我们有一些代码可以从文件中读取一些数据
fn read_username_from_file() -> Result<String, io::Error> {
let f = File::open("username.txt");
let mut f = match f {
Ok(file) => file,
Err(e) => return Err(e),
};
let mut s = String::new();
match f.read_to_string(&mut s) {
Ok(_) => Ok(s),
Err(e) => Err(e),
}
}
此代码有两条可能失败的路径:打开文件和从中读取数据。如果其中任何一个失败,我们希望从 read_username_from_file
返回一个错误。这样做需要对 I/O 操作的结果进行 match
。但是在像这样的简单情况下,我们只是将错误向上冒泡到调用堆栈,匹配只是样板代码——每次都以相同的模式编写它,并不能为读者提供大量有用的信息。
使用 ?
,上面的代码如下所示
fn read_username_from_file() -> Result<String, io::Error> {
let mut f = File::open("username.txt")?;
let mut s = String::new();
f.read_to_string(&mut s)?;
Ok(s)
}
?
是我们之前编写的整个匹配语句的简写。换句话说,?
应用于 Result
值,如果它是 Ok
,则解开它并给出内部值。如果它是 Err
,则从您当前所在的函数返回。从视觉上看,它更直接。现在我们只是使用单个“?”字符来表示我们在这里以标准方式处理错误,即通过将它们向上冒泡到调用堆栈,而不是使用整个匹配语句。
经验丰富的 Rust 程序员可能会认识到,这与自 Rust 1.0
以来可用的 try!
宏相同。实际上,它们是相同的。在 1.13 之前,read_username_from_file
可以像这样实现
fn read_username_from_file() -> Result<String, io::Error> {
let mut f = try!(File::open("username.txt"));
let mut s = String::new();
try!(f.read_to_string(&mut s));
Ok(s)
}
那么,当我们已经有一个宏时,为什么还要扩展该语言呢?原因有很多。首先,try!
已被证明非常有用,并且在惯用的 Rust 中经常使用。它被如此频繁地使用,以至于我们认为它值得拥有一个简洁的语法。这种演变是强大的宏系统的巨大优势之一:可以在不修改语言本身的情况下原型化和迭代语言语法的推测性扩展,并且作为回报,事实证明特别有用的宏可以指示缺少的功能。从 try!
到 ?
的这种演变就是一个很好的例子。
try!
需要更简洁语法的原因之一是,当连续使用多个 try!
调用时,它相当不吸引人。考虑
try!(try!(try!(foo()).bar()).baz())
而不是
foo()?.bar()?.baz()?
第一个在视觉上很难扫描,并且每一层的错误处理都会在表达式前面加上对 try!
的额外调用。这会将不必要的注意力放在微不足道的错误传播上,从而模糊了主代码路径,在本示例中,即对 foo
、bar
和 baz
的调用。这种带有错误处理的方法链接会发生在像构建器模式这样的情况下。
最后,专用的语法将使将来更容易生成专门针对 ?
定制的更友好的错误消息,而通常很难为宏扩展代码生成友好的错误(尽管在此版本中,?
错误消息可能需要改进)。
虽然这是一个很小的功能,但根据我们目前的经验,?
感觉是对旧的 try!
宏的稳固的人体工程学改进。这是 Rust 将继续获得的渐进式的、生活质量的改进的一个很好的例子,可以消除我们已经强大的基础语言的粗糙角落。
请在 RFC 243 中阅读有关 ?
的更多信息。
性能改进
最近,人们对编译器性能给予了很多关注。此版本中有一个好消息,而且还会有更多好消息。
Mark Simulacrum 和 Nick Cameron 一直在完善 perf.rust-lang.org,这是我们跟踪编译器性能的工具。它在专用硬件上定期运行 rustc-benchmarks 套件,并随时间跟踪结果。此工具记录编译器中每个通道的结果,并被编译器开发人员用来缩小性能回归的提交范围。它是我们工具箱的重要组成部分!
我们可以使用此工具来查看 1.13 开发周期中的性能图,如下所示。此周期涵盖了 8 月 16 日至 9 月 29 日的日期(该图从 8 月 25 日开始,并以几种方式过滤,以消除虚假、不完整或令人困惑的结果)。似乎有一些很大的减少,这些减少在相应的统计页面上进行了量化。
9 月 1 日的图表中显示的重大改进来自 Niko 的优化,该优化在翻译期间缓存规范化的投影。也就是说,在生成 LLVM IR 期间,编译器不再每次都需要时重新计算关联类型的具体实例,而是重用以前计算的值。此优化不会影响所有代码库,但在显示某些模式的代码库中,例如 futures-rs,其中调试模式构建时间提高了高达 40%,您会注意到差异。
另一个这样的优化,虽然不会影响每个 crate,但会以很大的方式影响一些 crate,来自 Michael Woerister,它改进了导出许多内联函数的 crate 的编译时间。当函数标记为 #[inline]
时,除了翻译该函数以供当前 crate 使用之外,编译器还会将其 MIR 表示形式存储在 crate rlib 中,并将该函数翻译为每个调用它的 crate 中的 LLVM IR。Michael 所做的优化在事后看来很明显:在某些情况下,内联函数仅供其他 crate 使用,而从不从定义它们的 crate 中调用;因此,编译器不需要翻译 crate 中内联函数的代码,除非它们被直接调用。这节省了 rustc 将函数转换为 LLVM IR 以及 LLVM 优化并将函数转换为机器代码的成本。
在某些情况下,这会导致显着的改进。ndarray crate 的构建时间提高了 50%,并且在(未发布的)winapi 0.3 crate 中,rustc 现在根本不发射机器代码。
但是,还有更多!Nick Nethercote 也将他的重点转向了编译器性能,专注于分析和微优化。此版本包含他工作的几个成果,并且 1.14 中还有更多成果即将推出。
其他值得注意的更改
此版本包含 Cargo 的重要安全更新,Cargo 依赖于 curl 和 OpenSSL,它们最近都发布了安全更新。有关更多信息,请参阅 curl 7.51.0 和 OpenSSL 1.0.2j 的相关公告。
现在可以在类型位置使用宏(RFC 873),并且可以将属性应用于语句(RFC 16)
// Use a macro to name a type
macro_rules! Tuple {
{ $A:ty,$B:ty } => { ($A, $B) }
}
let x: Tuple!(i32, i32) = (1, 2);
// Apply a lint attribute to a single statement
#[allow(non_snake_case)]
let BAD_STYLE = List::new();
内联 drop 标志已删除。以前,在条件移动的情况下,编译器会将“drop 标志”内联存储在结构体中(增加其大小),以跟踪是否需要 drop 它。这意味着某些结构体会占用一些意想不到的额外空间,这会干扰通过 FFI 传递具有析构函数的类型之类的事情。对于没有条件移动的代码来说,这也是浪费空间。在 1.12 中,MIR 成为默认,这为许多改进奠定了基础,包括摆脱这些内联 drop 标志。现在,drop 标志存储在需要它们的函数的堆栈帧的额外槽中。
1.13 包含一个使用硬件浮点数的 ARM 目标的代码生成中的严重错误(这是大多数 ARM 目标)。Rust 中的 ARM 目标目前处于我们的第二支持层,因此此错误未被确定为阻止发布。由于 1.13 包含安全更新,因此鼓励必须以 ARM 为目标的用户使用 1.14 beta 版本,该版本将很快获得 ARM 的修复程序。
语言稳定性
库稳定性
checked_abs
,wrapping_abs
, 和overflowing_abs
RefCell::try_borrow
, 和RefCell::try_borrow_mut
- 添加
assert_ne!
和debug_assert_ne!
- 为
std::slice::Iter
实现AsRef<[T]>
- 为
{Cell, RefCell, UnsafeCell}
实现CoerceUnsized
- 为
std::path::{Components,Iter}
实现Debug
- 为
char
实现转换 traits SipHasher
已被弃用。请使用DefaultHasher
。- 为
std::io::ErrorKind
实现更多 traits
Cargo 特性
请参阅详细版本说明以了解更多信息。
1.13.0 的贡献者
共有 155 位个人为 1.13.0 做出了贡献。非常感谢你们!
- Aaron Gallagher
- Abhishek Kumar
- aclarry
- Adam Medziński
- Ahmed Charles
- Aleksey Kladov
- Alexander von Gluck IV
- Alexandre Oliveira
- Alex Burka
- Alex Crichton
- Amanieu d'Antras
- Amit Levy
- Andrea Corradi
- Andre Bogus
- Andrew Cann
- Andrew Cantino
- Andrew Lygin
- Andrew Paseltiner
- Andy Russell
- Ariel Ben-Yehuda
- arthurprs
- Ashley Williams
- athulappadan
- Austin Hicks
- bors
- Brian Anderson
- c4rlo
- Caleb Jones
- CensoredUsername
- cgswords
- changchun.fan
- Chiu-Hsiang Hsu
- Chris Stankus
- Christopher Serr
- Chris Wong
- clementmiao
- Cobrand
- Corey Farwell
- Cristi Cobzarenco
- crypto-universe
- dangcheng
- Daniele Baracchi
- DarkEld3r
- David Tolnay
- Dustin Bensing
- Eduard Burtescu
- Eduard-Mihai Burtescu
- Eitan Adler
- Erik Uggeldahl
- Esteban Küber
- Eugene Bulkin
- Eugene R Gonzalez
- Fabian Zaiser
- Federico Ravasio
- Felix S. Klock II
- Florian Gilcher
- Gavin Baker
- Georg Brandl
- ggomez
- Gianni Ciccarelli
- Guillaume Gomez
- Jacob
- jacobpadkins
- Jake Goldsborough
- Jake Goulding
- Jakob Demler
- James Duley
- James Miller
- Jared Roesch
- Jared Wyles
- Jeffrey Seyfried
- JessRudder
- Joe Neeman
- Johannes Löthberg
- John Firebaugh
- johnthagen
- Jonas Schievink
- Jonathan Turner
- Jorge Aparicio
- Joseph Dunne
- Josh Triplett
- Justin LeFebvre
- Keegan McAllister
- Keith Yeung
- Keunhong Lee
- king6cong
- Knight
- knight42
- Kylo Ginsberg
- Liigo
- Manish Goregaokar
- Mark-Simulacrum
- Matthew Piziak
- Matt Ickstadt
- mcarton
- Michael Layne
- Michael Woerister
- Mikhail Modin
- Mohit Agarwal
- Nazım Can Altınova
- Neil Williams
- Nicholas Nethercote
- Nick Cameron
- Nick Platt
- Niels Sascha Reedijk
- Nikita Baksalyar
- Niko Matsakis
- Oliver Middleton
- Oliver Schneider
- orbea
- Panashe M. Fundira
- Patrick Walton
- Paul Fanelli
- philipp
- Phil Ruffwind
- Piotr Jawniak
- pliniker
- QuietMisdreavus
- Rahul Sharma
- Richard Janis Goldschmidt
- Scott A Carr
- Scott Olson
- Sean McArthur
- Sebastian Ullrich
- Sébastien Marie
- Seo Sanghyeon
- Sergio Benitez
- Shyam Sundar B
- silenuss
- Simonas Kazlauskas
- Simon Sapin
- Srinivas Reddy Thatiparthy
- Stefan Schindler
- Stephan Hügel
- Steve Klabnik
- Steven Allen
- Steven Fackler
- Terry Sun
- Thomas Garcia
- Tim Neumann
- Tobias Bucher
- Tomasz Miąsko
- trixnz
- Tshepang Lekhonkhobe
- Ulrich Weigand
- Ulrik Sverdrup
- Vadim Chugunov
- Vadim Petrochenkov
- Vanja Cosic
- Vincent Esche
- Wesley Wiser
- William Lee
- Ximin Luo
- Yossi Konstantinovsky
- zjhmale