Appearance
1.1 版本和发布策略
Rust 编程语言是开源的,编译器的源码位于 rust-lang/rust,语言设计和相关讨论位于 rust-lang/rfcs 项目中。对于想深入研究这门语言的读者来说,这是一个非常好的消息,大家可以通过研读开放的源代码和技术文档了解到很多书本上没有讲解过的知识。任何一个开发者都可以直接给这个项目提 bug,或者直接贡献代码。Rust 项目是完全由开源社区管理和驱动的,社区的氛围非常友好。
Rust 编译器的版本号采用了“语义化版本号”(Semantic Versioning)规划。在这个规则之下,版本格式为:主版本号。次版本号.修订号。版本号递增规则如下。
- 主版本号:当你做了不兼容的 API 修改
- 次版本号:当你做了向下兼容的功能性新增
- 修订号:当你做了向下兼容的问题修正
Rust 的第一个正式版本号是 1.0,是 2015 年 5 月发布的。从那以后,只要版本没有出现大规模的不兼容的升级,大版本号就一直维持在“1”,而次版本号会逐步升级。Rust 一般以 6 个星期更新一个正式版本的速度进行迭代。
为了兼顾更新速度以及稳定性,Rust 工具链分为三个发布渠道:
- nightly 版本
- beta 版本
- stable 版本
版本类型 | 描述 |
---|---|
Nightly | 每天从 develop 的主分支自动创建出来的版本,这个版本包含所有最新功能,但是某些功能存在问题的可能性也更大。因为新功能会首先在这个版本上开启,供用户试用。 |
Beta | 每六周发布一次。将一些在 nightly 版本中验证过的功能开放给用户使用。它可以被看作 stable 版本的“预发布”版本。 |
Stable | 正式版,每六周发布一个新版本,一些实验性质的新功能在此版本上无法使用。它也是最稳定、最可靠的版本。stable 版本是保证向前兼容的。 |
鼓励开发人员使用稳定版本渠道。但是,Nightly 版本启用了前沿的不稳定功能,某些库和程序可能会需要此功能。您可以通过 rustup 轻松地更改为 Nightly 工具链。
在 nightly 版本中使用试验性质的功能,必须手动开启 feature gate。也就是说要在当前项目的入口文件中加入一条#![feature(...name...)]
语句。否则是编译不过的。等到这个功能最终被稳定了,再用新版编译器编译的时候,它会警告你这个 feature gate 现在是多余的了,可以去掉了。
Rust 语言相对重大的设计,必须经过 RFC(Request For Comments)设计步骤。这个步骤主要是用于讨论如何“设计”语言。 所有大功能必须先写好设计文档,讲清楚设计的目标、实现方式、优缺点等,让整个社区参与讨论,然后由“核心组”(Core Team)的成员参与定夺是否接受这个设计。 强烈建议各位读者多读一下 RFC 文档,许多深层次的设计思想问题可以在这个项目中找到答案。 在 Rust 社区,我们不仅可以看到最终的设计结果,还能看到每一步设计的过程,对我们来说非常有教育意义。
Rust 语言每个相对复杂一点的新功能,都要经历如下步骤才算真正稳定可用:
RFC → Nightly → Beta → Stable
先编写一份 RFC,其中包括这个功能的目的、详细设计方案、优缺点探讨等。如果这个 RFC 被接受了,下一步就是在编译器中实现这个功能,在 nightly 版本中开启。经过几个星期甚至几个月的试用之后,根据反馈结果来决定撤销、修改或者接受这个功能。如果表现不错,它就会进入 beta 版本,继续过几个星期后,如果确实没发现什么问题,最终会进入 stable 版本。至此,这个功能才会被官方正式定为“稳定的”功能,在后续版本中要确保兼容性的。
这个发布策略非常成功,它保证了新功能可以持续、快速地进入到编译器中。在这个发布策略的支持下,Rust 语言以及编译器的进化速度非常了不起,成功实践了快速迭代、敏捷交付以及重视用户反馈的特点,同时也保证了核心设计的稳定性——用户可以根据自己的需要和风险偏好,选择合适的版本。
本书假定读者安装的是 nightly 版本,因为我们的目标是学习,目前有许多重要的功能只存在于 nightly 版本。
在 2017 年下半年,Rust 设计组又提出了一个基于 epoch 的演进策略(后来也被称为 edition)。它要解决的问题是,如何让 Rust 更平稳地进化。比如,有时某些新功能确实需要一定程度上破坏兼容性。为了最大化地减少这些变动给用户带来的影响,Rust 设计组又设计了一个所谓的 edition 的方案。简单来说就是让 Rust 的兼容性保证是一个有时限的长度,而不是永久。Rust 设计组很可能会在不久的将来发布一个 2018 edition,把之前的版本叫作 2015 edition。在这个版本的进化过程中,就可以实施一些不兼容的改变。当然了,Rust 设计组不会突然让前一个 edition 的代码到了后一个 edition 就不能编译了。他们采用了一种平滑过渡的方案。
我们举个例子。假设我们要添加一个功能,比如增加一个关键字。这件事情肯定是不兼容的改变,因为用户写的代码中很可能包含用这个关键字命名的变量、函数、类型等,直接把这个单词改成关键字会直接导致这些遗留代码出现编译错误。那怎么办呢?首先会在下一个 edition 中做出警告,提示用户这个单词已经不适合作为变量名了,请用户修改。但是这个阶段代码依然能编译通过。然后到再下一个 edition 的时候,这个警告就会变成真正的编译错误,此时这个关键字就可以真正启用了。先编译警告,再编译错误,这个过程可能会持续好几年,所以 Rust 的稳定性还是基本上有保证的。毕竟,如果要维持百分之百的兼容性,Rust 语言就很难再继续进化了。如果让极少一部分受影响的遗留代码,完全锁死整个语言的进步空间,对于那些特别需要某些新功能的用户来说也是不公平的。通过这个缓慢过渡的策略,基本可以让所有 Rust 的使用者平滑、无痛地过渡到新版本。几年的过渡时间也是足够充分的。
Rust 的标准库文档位于:https://doc.rust-lang.org/std/ 。学会查阅标准库文档,是每个 Rust 使用者的必备技能之一。