Rust开发团队很高兴地宣布发布Rust的新版本:1.30.0。 Rust是一种针对安全性,速度和并行代码执行的系统编程语言。
如果您使用rustup
安装了先前版本的Rust,那么要将Rust升级到1.30.0版本,您只需执行以下操作:
$ rustup update stable
如果尚未安装rustup
,则可以从我们网站的相应页面进行安装 。 可以在GitHub上找到Rust 1.30.0的详细发行说明 。
稳定版1.30.0中包含什么
Rust 1.30是具有许多重要创新的出色发行版。 但是在星期一,官方博客将发布请求,以检查Rust 1.31的beta版本,这将是“ Rust 2018”的第一个版本。 您可以在我们之前的出版物“ What is Rust 2018”中找到有关此的更多信息。
程序宏
回到Rust 1.15,我们添加了定义“自定义派生宏”的功能。 例如,使用serde_derive
,您可以声明:
#[derive(Serialize, Deserialize, Debug)] struct Pet { name: String, }
并将Pet
转换为JSON并使用serde_json
返回结构。 这可以归功于使用serde_derive
过程宏对Serialize
和Deserialize
Serialize
Deserialize
的自动推断。
Rust 1.30通过添加定义两种其他类型的宏的功能来扩展过程宏的功能:“属性过程宏”和“功能过程宏”。
属性宏类似于自动输出的派生宏,但是它们不仅仅为#[derive]
属性生成代码,而是允许用户创建自己的新属性。 这使它们更加灵活:派生宏仅适用于结构和枚举,但是属性可以应用于其他对象,例如函数。 例如,使用网络框架时,属性宏将允许您执行以下操作:
#[route(GET, "/")] fn index() {
此属性#[route]
将在框架本身中定义为程序宏。 他的签名将如下所示:
#[proc_macro_attribute] pub fn route(attr: TokenStream, item: TokenStream) -> TokenStream {
在这里,我们有两个TokenStream
类型的输入参数:第一个是属性本身的内容,即GET, "/"
参数GET, "/"
。 第二个是应用属性的对象的主体。 在我们的例子中,这是fn index() {}
和函数主体的其余部分。
功能宏定义了其用法类似于函数调用的宏。 例如, sql!
:
let sql = sql!(SELECT * FROM posts WHERE id=1);
这个宏本身将解析SQL表达式并检查其语法正确性。 类似的宏应声明如下:
#[proc_macro] pub fn sql(input: TokenStream) -> TokenStream {
这类似于derive宏的签名:我们获得括号内的令牌,并返回由它们生成的代码。
宏和use
现在,您可以使用use关键字将宏导入作用域 。 例如,要使用serde-json
包中的json
宏,该条目以前为:
#[macro_use] extern crate serde_json; let john = json!({ "name": "John Doe", "age": 43, "phones": [ "+44 1234567", "+44 2345678" ] });
现在,您将必须编写:
extern crate serde_json; use serde_json::json; let john = json!({ "name": "John Doe", "age": 43, "phones": [ "+44 1234567", "+44 2345678" ] });
在这里,宏以及其他元素也被导入,因此不需要使用macro_use
批注。
最后, proc_macro软件包已稳定下来 ,它提供了编写过程宏所需的API。 它还大大改善了错误处理API,并且syn
和quote
这样的程序包已经在使用它。 例如,先前:
#[derive(Serialize)] struct Demo { ok: String, bad: std::thread::Thread, }
导致此错误:
error[E0277]: the trait bound `std::thread::Thread: _IMPL_SERIALIZE_FOR_Demo::_serde::Serialize` is not satisfied --> src/main.rs:3:10 | 3 | #[derive(Serialize)] | ^^^^^^^^^ the trait `_IMPL_SERIALIZE_FOR_Demo::_serde::Serialize` is not implemented for `std::thread::Thread`
现在将发布:
error[E0277]: the trait bound `std::thread::Thread: serde::Serialize` is not satisfied --> src/main.rs:7:5 | 7 | bad: std::thread::Thread, | ^^^ the trait `serde::Serialize` is not implemented for `std::thread::Thread`
改善模块系统
长期以来,模块系统一直是Rust初学者的痛点; 它的某些规则在实践中不方便。 这些更改是我们简化模块系统所采取的第一步。
除了上述对宏的更改之外,使用use
还有两个新的改进。 首先, 现在将外部软件包添加到前奏中 ,即:
值得注意的是,由于Rust模块系统的功能,并不总是需要旧样式:
extern crate serde_json; fn main() { // ; , `serde_json` // let json = serde_json::from_str("..."); } mod foo { fn bar() { // ; `foo`, `serde_json` // let json = serde_json::from_str("..."); } // - `use` use serde_json; fn baz() { // - `::serde_json`, // , let json = ::serde_json::from_str("..."); } }
只需将函数移至子模块即可破坏代码,这很烦人。 现在将检查路径的第一部分,如果它对应于某个extern crate
,则无论调用在模块层次结构中的位置如何,都将使用它。
最后, use开始支持使用以crate开头的路径将元素导入当前范围 :
mod foo { pub fn bar() {
路径开头的crate
关键字表示路径将从数据包的根开始。 以前, use
导入行中指示的路径始终是相对于包的根目录指定的,但是直接引用元素的其余代码中的路径是相对于当前模块指定的,这导致路径的行为不一致:
mod foo { pub fn bar() {
新样式一经广泛使用,就有望使绝对路径更清晰,而无需使用丑陋的前缀::
。
所有这些更改共同简化了对路径解析方式的理解。 无论您在哪里看到路径a::b::c
,除了use
语句,您都可以问:
- 是包裹名称吗? 然后,您需要在其中查找
b::c
。 - 是关键字
crate
吗? 然后,您需要从当前包的根目录中查找b::c
。 - 否则,您需要从模块层次结构中的当前位置查找
a::b::c
。
始终从包根开始use
中路径的旧行为仍然适用。 但是,一次性过渡到新样式后,这些规则将统一应用于所有路径,并且在移动代码时您不必担心导入。
原始标识符
现在,您可以使用以下新语法将关键字用作标识符 :
到目前为止,对您有用的情况并不多。 但是有一天,您将在Rust 2018的项目中尝试使用Rust 2015的软件包,反之亦然,那么它们的关键字集会有所不同。 我们将在即将发布的Rust 2018公告中进一步讨论这一点。
没有标准库的应用程序
在Rust 1.6中,我们宣布了稳定“ no_std”和libcore的功能,以创建没有标准库的项目。 但是,有一个澄清:可以仅创建库,而不能创建应用程序。
在Rust 1.30中,可以使用#[panic_handler]
属性独立实现恐慌。 这意味着现在您可以创建应用程序,而不仅仅是不使用标准库的库。
其他
最后一件事:在宏中,您现在可以使用vis
限定符映射范围修饰符 ,例如pub
。 此外,“稳定的工具属性”(例如#[rustfmt::skip]
) 现在已稳定 。 适用于静态分析工具 ,例如#[allow(clippy::something)]
,它们尚不稳定。
有关更多详细信息,请参见发行说明 。
稳定标准库
此版本中稳定了以下API :
Ipv4Addr::{BROADCAST, LOCALHOST, UNSPECIFIED}
Ipv6Addr::{BROADCAST, LOCALHOST, UNSPECIFIED}
Iterator::find_map
此外,标准库长期以来就有删除某些文本一侧空格的功能,例如trim_left
。 但是,对于RTL语言,此处“右”和“左”的含义会引起混淆。 因此,我们为这些功能引入了新的名称:
trim_left
> trim_start
trim_right
> trim_end
trim_left_matches
> trim_start_matches
trim_right_matches
> trim_end_matches
我们计划在Rust 1.33中声明旧名称(但不能删除)。
有关更多详细信息,请参见发行说明 。
货运增强
此版本中对Cargo的最大改进是,我们现在有了进度栏!

有关更多详细信息,请参见发行说明 。
开发人员1.30.0
很多人一起创建了Rust 1.30。 没有你们每个人,我们不可能完成工作。 谢谢你
译者:我特别感谢Rustycrate社区的成员以及vitvakatu和Virtuos86的翻译和校对工作。