Rust 1.31和Rust 2018版本

Rust开发团队很高兴地宣布发布Rust的新版本1.31.0以及“ Rust 2018”。 Rust是一种编程语言,使每个人都可以创建可靠且高效的软件。


如果您使用rustup安装了先前版本的Rust,那么要将Rust升级到版本1.31.0,您只需执行以下操作:


 $ rustup update stable 

如果尚未安装rustup ,则可以从我们网站的相应页面进行安装 。 可以在GitHub上找到Rust 1.31.0的详细发行说明


稳定版1.31.0中包含什么


Rust 1.31可以说是自Rust 1.0以来最重要的版本! 此版本中包含“ Rust 2018”的第一次迭代,但这并不是唯一的创新! 改进的审查很长,因此这里是目录:


  • 锈2018
    • 非词汇时代
    • 模块系统变更
  • 显示寿命的其他规则
  • const fn
  • 新工具
  • 工具代码质量检查
  • 该文件
  • 主题工作组
  • 新网站
  • 稳定标准库
  • 货运增强
  • 发布开发人员

锈2018


我们在3月7月 第一次写了Rust 2018。 有关为什么需要Rust 2018的详细信息,请参阅这些出版物。 在这篇评论中,有太多要告诉我们的内容,因此我们仅关注Rust 2018的全部内容,您也可以在Mozilla Hacks的帖子中阅读( 翻译 )。


简而言之,Rust 2018是将我们过去三年中所做的所有工作整合为一个连贯整体的机会。 Rust 2018不仅仅是对语言的改进。 除它们之外,它还包括:


  • 工具包(IDE, rustfmt和Clippy中的支持)
  • 该文件
  • 主题工作组
  • 新网站

此外,我们将更详细地讨论所有这些以及其他创新。


让我们使用Cargo创建一个新项目:


 $ cargo new foo 

这是Cargo.toml的内容:


 [package] name = "foo" version = "0.1.0" authors = ["Your Name <you@example.com>"] edition = "2018" [dependencies] 

新的密钥已添加到[package]部分: edition 。 请注意,它2018安装。 您也可以在2015年安装它-如果缺少密钥,则默认情况下会设置此值。


使用Rust 2018将解锁Rust 2015中不允许的一些新功能。


重要的是要注意,每个软件包都可以处于2015或2018模式,并且它们可以一起工作。 您的2018版本项目可以使用2015版本依赖关系,而2015版本项目可以使用2018版本依赖关系。 这样可以确保生态系统的完整性,并且所有新功能都是可选的,同时保持与现有代码的兼容性。 此外,当您决定将Rust 2015代码移植到Rust 2018时,可以通过cargo fix自动进行更改。


您可能会问:新功能本身如何? 首先,如果它们与该版本的功能兼容,它们也会在Rust 2015中添加。 因此,大多数语言到处都是相同的。 您可以查看编辑手册,以了解每个新功能及其其他要求的最低rustc版本。 但是,有几项重大创新需要分别提及:非词法生存期和模块系统中的某些更改。


非词汇时代


如果您在过去的几年中一直关注Rust,那么您可能偶尔会遇到“ NLL”或“非词汇寿命”一词。 这是行话,简单来说,意思是:借款人变得更聪明,现在接受一些正确的代码,而以前它拒绝了。 考虑一个例子:


 fn main() { let mut x = 5; let y = &x; let z = &mut x; } 

Rust经常引发编译错误:


 error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable --> src/main.rs:5:18 | 4 | let y = &x; | - immutable borrow occurs here 5 | 6 | let z = &mut x; | ^ mutable borrow occurs here 7 | } | - immutable borrow ends here 

这是因为链接的生存区域是“按词法”定义的; 也就是说,即使我们不再在范围内再次使用y ,借用y才被视为活动状态,直到ymain的末尾超出范围为止。 上面的代码一切都很好,但是依赖分析器无法理解这一点。


现在,此代码可以正常编译。


但是,如果我们使用y怎么办? 例如,像这样:


 fn main() { let mut x = 5; let y = &x; let z = &mut x; println!("y: {}", y); } 

Rust曾经给你这个错误:


 error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable --> src/main.rs:5:18 | 4 | let y = &x; | - immutable borrow occurs here 5 | let z = &mut x; | ^ mutable borrow occurs here ... 8 | } | - immutable borrow ends here 

在Rust 2018中,此错误消息得到了改进:


 error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable --> src/main.rs:5:13 | 4 | let y = &x; | -- immutable borrow occurs here 5 | let z = &mut x; | ^^^^^^ mutable borrow occurs here 6 | 7 | println!("y: {}", y); | - borrow later used here 

它没有显示y超出范围的地方,而是显示发生冲突的借用的地方。 这大大简化了此类调试错误。


在Rust 1.31中,这是对Rust 2018的专门改进。我们计划稍后将其添加到Rust 2015中。


模块系统变更


对于初次学习Rust的人来说,模块系统可能会很困难。 当然,总有一些东西需要花费时间来掌握。 但是,模块之所以让许多人感到尴尬的主要原因是,尽管定义了模块系统的规则简单而一致,但使用它们的后果却似乎是矛盾的,神秘的和不自然的。


因此,2018版对路径的工作方式进行了一些更改,从而简化了模块系统并使之更易于理解。


这是一个简短的摘要:


  • 几乎其他任何地方都不再需要extern crate
  • 您可以使用use导入宏,而不要使用#[macro_use]属性。
  • 绝对路径以容器名称开头,其中crate关键字引用当前容器。
  • foo.rsfoo/子目录可以共存; 将子模块放在子目录中时,不再需要mod.rs

它看起来像一组任意规则,但是总体上,现在已经大大简化了心理模型。


还有很多细节,所有细节请参考编辑手册


显示寿命的其他规则


让我们谈谈两个版本中可用的改进:我们为impl块和函数定义添加了一些其他推理规则。 像这样的代码:


 impl<'a> Reader for BufReader<'a> { //   } 

现在可以这样写:


 impl Reader for BufReader<'_> { //   } 

生命周期'_仍然显示BufReader将其作为参数,但是我们不再需要为其命名。


寿命仍然需要在结构中定义。 但是,我们不再需要像以前那样编写更多的样板代码:


 // Rust 2015 struct Ref<'a, T: 'a> { field: &'a T } // Rust 2018 struct Ref<'a, T> { field: &'a T } 

相关性: 'a将被输出。 您仍然可以根据需要明确指定它。 我们正在考虑将来在这些地方撤出其他机会,但到目前为止,我们还没有具体计划。


const fn


Rust有几种方法来声明函数: fn用于普通函数, unsafe fn用于不安全函数, extern fn用于外部函数。 此版本增加了一种声明函数的新方法: const fn 。 它的用法如下:


 const fn foo(x: i32) -> i32 { x + 1 } 

常量函数可以称为普通函数,但除此之外,它可以在任何常量上下文中使用。 但是,它将在编译时执行,而不是在程序执行期间执行。 例如:


 const SIX: i32 = foo(5); 

foo函数将在编译时执行,并且SIX将设置为6


常量函数无法完成普通函数可以做的所有事情:它们必须具有确定性的结果。 出于可靠性考虑,这一点很重要。 以当前形式,常量函数可以执行最少的操作子集。 以下是您可以在其中执行的操作的一些示例:


  • 使用整数算术和比较运算
  • 使用&&||以外的任何逻辑运算
  • 设计数组,结构,枚举和元组
  • 调用其他常量函数
  • 通过索引访问数组和切片
  • 访问结构和元组的字段
  • 使用常量(但不要使用静态值,甚至不要引用它们)
  • 使用&*链接
  • 强制类型转换,除了将原始指针转换为整数值

我们将扩展常量函数的功能,但是上面的设置已经足够在实践中使用const fn了。


有关详细信息,请参见手册


新工具


2018年版本标志着Rust工具生态系统达到新的成熟水平的开始。 自1.0版以来,Cargo,Rustdoc和Rustup一直是主要工具。 随着2018年版本的出现,新一代工具已经面世,每个人现在都可以使用:Clippy,Rustfmt和IDE支持。


clippy静态代码分析器现在可以在稳定的Rust中使用。 您可以通过rustup component add clippy进行安装,并使用cargo clippy运行它。 Clippy现在已经收到1.0版,并且具有与rustc相同的静态检查稳定性保证。 可以添加新支票,或者可以扩展旧支票的功能,但是不能删除旧支票(只能将其标记为过时的)。 这意味着使用clippy编译的代码将继续使用clippy编译(假定未设置检查以生成
错误(通过deny ),但可能会生成新的警告。


Rustfmt是用于在Rust中格式化代码的工具。 自动代码格式化将节省您的时间,此外,它将使您的代码更接近于Rust正式样式 。 您可以通过rustup component add rustfmt进行安装,并使用cargo fmt命令。


当前版本包括Rustfmt 1.0。 从现在开始,我们保证Rustfmt的向后兼容性:如果您今天格式化代码,那么以后的格式将不会更改(仅适用于默认设置)。 向后兼容意味着现在可以在CI上运行Rustfmt(使用cargo fmt --check )。 在编辑器中将其与“保存时格式化”一起尝试,这将彻底改变您的工作流程。


IDE支持是Rust最需要的功能之一。 现在有几种高质量的解决方案:



IDE中的支持工作尚未完成。 尤其是,基于RLS的编辑器中的代码完成不符合标准。 但是,如果您主要希望支持类型,文档和“到定义的转换”,那么您会感到满意的。


仪器代码质量检查(工具棉绒)


Rust 1.30中,我们稳定了“工具属性”,例如#[rustfmt::skip] 。 在Rust 1.31中,我们稳定了以下内容: #[allow(clippy::bool_comparison)]类的“ tool lints”。 这使您可以为检查指定名称空间,以更清楚地了解它们来自什么工具。


如果您以前使用过Clippy检查,则可以按以下方式迁移:


 //  #![cfg_attr(feature = "cargo-clippy", allow(bool_comparison))] //  #![allow(clippy::bool_comparison)] 

您不再需要cfg_attr ! 您现在还将收到警告,可以帮助您切换到使用新样式。


该文件


今年,Rustdoc进行了一些改进,并完全重写了《 Rust编程语言》一书。 您可以从No Starch Press购买纸质副本


它以前被称为这本书的“第二版”,但是由于它成为第一版印刷,因此引起了混乱。 毕竟,印刷版计划要定期更新。 最后,在与No Starch进行了多次讨论之后,决定在每个发行版的网站上进行更新,No Starch会定期提取并打印更改。 这本书卖得很好,并为《 黑人女孩守则》筹集了资金。


您可以在此处找到该书的新版本。


主题工作组


今年,我们宣布成立四个工作组:


  • 网络服务
  • 命令行应用
  • 网络组装
  • 嵌入式设备

这些小组非常努力地使Rust在这些领域中都变得更好。 以下是一些成就:


  • 网络服务重新设计了期货的接口,此外还异步/等待。 这些改进尚未发布,但我们已经接近了!
  • CLI团队研究库和文档,以使命令行应用程序更好。
  • WebAssembly发布了许多世界一流的工具,可将Rust与wasm一起使用。
  • 对于嵌入式设备,可以在稳定的Rust上开发ARM!

您可以在我们的新网站上了解更多关于这一切的信息!


新网站


上周,我们宣布了我们网站的新版本。 现在它已经成为rust-lang.org的正式版本!


要创建它需要许多人花费一年的时间。 尽管在完成之前还有很多工作要做,但是我们为完成的工作感到自豪。


稳定标准库


添加了新的From实现:


  • u8现在实现From<NonZeroU8> ,对于其他数字类型及其等效的NonZero
  • Option<&T> From<&Option<T>> &mut类似,实现了From<&Option<T>>

以下功能也已稳定:



有关更多详细信息,请参见发行说明


货运增强


现在,货运将使用HTTP / 2并行加载包裹。


另外,由于extern crate现在extern crate可选的,因此将extern crate foo as bar;编写extern crate foo as bar;会令人沮丧extern crate foo as bar; 重命名依赖关系。 因此,您可以Cargo.toml以下方式在Cargo.toml


 [dependencies] baz = { version = "0.1", package = "foo" } 

或等效地:


 [dependencies.baz] version = "0.1" package = "foo" 

foo软件包现在可以baz在您的代码中使用。


有关更多详细信息,请参见发行说明


开发人员1.31.0


通常,在审阅结束时,我们感谢为发布做出贡献人们 。 但是这次,与过去不同,此列表并未完全涵盖所有提供帮助的人员以及已完成的所有工作。 每个定期发布都是六个星期的工作结果,但此发布是三年努力的结晶,这反映在大量人员创建的大量存储库中。 我们很高兴与大家一起工作,我们期待Rust在未来三年中继续发展。


译者:我要特别感谢Rustycrate社区的成员,并亲自感谢@dashadeeozkriffhumbugmvlabat的翻译和校对工作。

Source: https://habr.com/ru/post/zh-CN432640/


All Articles