Rust crates 使用 Semantic Versioning .因此,每个具有重大更改的版本都应该导致主要版本升级。 重大变更通常被认为可能会破坏下游 crate (代码取决于相关库)。
但是,在 Rust 中,很多东西都有可能破坏下游的 crate 。例如,更改(仅包括添加)公共(public)符号集可能是一个重大更改,因为下游 crate 可以使用 glob-imports(use foo::*;
) 将我们库的符号拉入它们的命名空间。因此,添加符号也可以破坏依赖的 crate ;见this example .
同样,更改(添加或更改版本)我们的 依赖项集可能会破坏下游构建。您还可以想象下游 crate 依赖于我们的一种公共(public)类型的特定大小。这很少(如果有的话)有用;我只是想表明:只要下游 crate 足够努力,一切都可能是一个突破性的变化。
有这方面的指导方针吗? 究竟什么被认为是重大更改,什么不是(因为它被认为是“用户的错”)?
最佳答案
有一个关于这个主题的 Rust RFC:RFC 1105: API Evolution .它适用于任何 Rust 库项目,涵盖所有类型的更改(不仅仅是破坏性更改)以及它们如何影响语义版本控制。我将尝试总结 RFC 中的要点,以免使此答案成为仅链接的答案。 :)
RFC 承认几乎任何对库的更改都可能导致客户端突然停止编译。因此,它定义了一组主要变化,这需要主版本号的变化,以及一组次要变化,这需要次要版本的变化数字;并非所有重大更改都是重大更改。
微小变化的关键属性是必须有一种方法可以让客户通过稍微改变他们的源代码来提前避免破坏(例如,将 glob 导入更改为非 glob 导入,用 UFCS 消除歧义调用, 等等),使得代码与更改之前的版本以及包含更改的版本(假设它是次要版本)兼容。微小的变化也不得迫使下游 crate 进行重大的破坏性变化以解决破损问题。
RFC 中定义的主要更改(自 commit 721f2d74
起)是:
- 将您的项目从与稳定编译器兼容改为仅与夜间编译器兼容。
- 重命名、移动或删除任何公共(public) item在模块中。
- 当所有当前字段都是公共(public)字段时,将私有(private)字段添加到结构。
- 将公共(public)字段添加到没有私有(private)字段的结构。
- 向枚举添加新变体。
- 向枚举变体添加新字段。
- 将非默认项添加到特征。
- 对特征项签名的任何重要更改。
- 实现 fundamental现有类型的特征。
- 收紧现有类型参数的界限。
- 向函数添加或删除参数。
- 未在 RFC 中列为次要更改的任何其他重大更改。
RFC 中定义的微小变化(自 commit 721f2d74
起,除非另有说明,否则为中断)是:
- 更改 crate 上 Cargo 功能的使用。
- 在模块中添加新的公共(public)项。
- 在结构中至少已经存在一个私有(private)字段时(更改前后)添加或删除私有(private)字段[不中断]。
- 将包含所有私有(private)字段(至少包含一个字段)的元组结构转换为普通结构,反之亦然。
- 将默认项添加到特征。
- 将默认类型参数添加到特征[不破坏]。
- 在现有类型上实现任何非基本特征。
- 将任何项目添加到固有的
impl
。 - 更改函数的未记录行为。
- 放宽现有类型参数的界限[不破坏]。
- 将默认类型参数添加到类型或特征[不破坏]。
- 通过将其类型替换为默认为先前类型的新类型参数来泛化现有结构或枚举字段[breaking until issue 27336是固定的]。
- 将新类型参数引入现有函数。
- 通过将类型替换为可实例化为先前类型的新类型参数来泛化参数或现有函数的返回类型。
- 引入新的 lint 警告/错误。
参见 the RFC用于解释和示例。
关于rust - 究竟什么被认为是对库箱的重大改变?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41185023/