简体   繁体   English

究竟什么被认为是图书馆箱子的重大变化?

[英]What exactly is considered a breaking change to a library crate?

Rust crates use Semantic Versioning . Rust crates 使用语义版本控制 As a consequence, each release with a breaking change should result in a major version bump.因此,每个具有重大更改的版本都应该导致主要版本的提升。 A breaking change is commonly considered something that may break downstream crates (code the depends on the library in question).破坏性更改通常被认为可能会破坏下游 crate(编码取决于相关库)。

However, in Rust a whole lot has the potential of breaking downstream crates.然而,在 Rust 中,很多东西都有可能破坏下游的 crate。 For example, changing (including merely adding to ) the set of public symbols is possibly a breaking change, because downstream crates can use glob-imports ( use foo::*; ) to pull symbols of our library into their namespace.例如,更改(包括仅添加到)公共符号集可能是一个重大更改,因为下游 crate 可以使用 glob-imports( use foo::*; )将我们库的符号拉入其命名空间。 Thus, adding symbols can break dependent crates as well;因此,添加符号也可以破坏依赖包; see this example .这个例子

Similarly, changing (adding or changing the version) the set of our dependencies can break downstream builds.类似地,更改(添加或更改版本)我们的依赖项集可能会破坏下游构建。 You can also imagine that the downstream crate relies on a specific size of one of our public types.您还可以想象下游 crate 依赖于我们公共类型之一的特定大小。 This is rarely, if at all, useful;这很少(如果有的话)有用; I just want to show: everything could be a breaking change, if only the downstream crate tries hard enough.我只想表明:只要下游板条箱足够努力,一切都可能是一个突破性的变化。

Is there any guideline about this?是否有任何指导方针? What exactly is considered a breaking change and what not (because it's considered "the user's fault")?究竟什么被认为是重大更改,什么不是(因为它被认为是“用户的错”)?

There is a Rust RFC on this subject: RFC 1105: API Evolution .有一个关于这个主题的 Rust RFC: RFC 1105: API Evolution It's applicable to any Rust library project, and it covers all kinds of changes (not just breaking changes) and how they impact semantic versioning.它适用于任何 Rust 库项目,它涵盖了所有类型的更改(不仅仅是破坏性更改)以及它们如何影响语义版本控制。 I'll try to summarize the key points from the RFC in order to not make this answer a link-only answer.我将尝试总结 RFC 中的关键点,以免此答案成为仅链接的答案。 :) :)

The RFC acknowledges that pretty much any change to a library can cause a client to suddenly stop compiling. RFC 承认对库的几乎任何更改都可能导致客户端突然停止编译。 As such, it defines a set of major changes , which require a bump of the major version number, and a set of minor changes , which require a bump of the minor version number;因此,它定义了一组主要更改,需要增加主版本号,以及一组次要更改,需要增加次要版本号; not all breaking changes are major changes .并非所有重大变化都是重大变化

The key attribute of a minor change is that there must be a way that clients can avoid the breakage in advance by altering slightly their source code (eg change a glob import to a non-glob import, disambiguate an ambiguous call with UFCS, etc.) in such a way that the code is compatible with the version prior to the change and with the version that includes the change (assuming that it's a minor release).微小更改的关键属性是必须有一种方法使客户端可以通过稍微更改其源代码(例如,将 glob 导入更改为非 glob 导入,使用 UFCS 消除歧义调用等)来提前避免损坏。 ) 以使代码与更改之前的版本以及包含更改的版本兼容(假设它是次要版本)。 A minor change must also not force downstream crates to make major breaking changes in order to resolve the breakage.微小的更改也不得迫使下游的板条箱进行重大的破坏性更改以解决破损问题。


The major changes defined in the RFC (as of commit 721f2d74 ) are: RFC 中定义的主要更改(截至提交721f2d74 )是:

  • Switching your project from being compatible with the stable compiler to only being compatible with the nightly compiler.将您的项目从与稳定编译器兼容切换为仅与夜间编译器兼容。
  • Renaming, moving or removing any public item in a module.重命名、移动或删除模块中的任何公共项目
  • Adding a private field to a struct when all current fields are public.当所有当前字段都是公共字段时,将私有字段添加到结构中。
  • Adding a public field to a struct that has no private fields.将公共字段添加到没有私有字段的结构中。
  • Adding new variants to an enum.向枚举添加新变体。
  • Adding new fields to an enum variant.向枚举变体添加新字段。
  • Adding a non-defaulted item to a trait.将非默认项添加到特征中。
  • Any non-trivial change to the signature of a trait item.对特征项签名的任何非平凡更改。
  • Implementing a fundamental trait on an existing type.在现有类型上实现基本特征。
  • Tightening bounds on an existing type parameter.收紧现有类型参数的界限。
  • Adding or removing arguments to a function.添加或删除函数的参数。
  • Any other breaking change that is not listed as a minor change in the RFC.未在 RFC 中列为次要更改的任何其他重大更改。

The minor changes defined in the RFC (as of commit 721f2d74 , breaking unless specified) are: RFC 中定义的小改动(从提交721f2d74 ,除非指定,否则为破坏):

  • Altering the use of Cargo features on a crate.改变货箱上货物功能的使用。
  • Adding new public items in a module.在模块中添加新的公共项目。
  • Adding or removing private fields in a struct when at least one already exists (before and after the change) [not breaking] .当至少一个已经存在时(在更改之前和之后)添加或删除结构中的私有字段[不破坏]
  • Turning a tuple struct with all private fields (with at least one field) into a normal struct, or vice versa.将具有所有私有字段(至少有一个字段)的元组结构转换为普通结构,反之亦然。
  • Adding a defaulted item to a trait.将默认项添加到特征。
  • Adding a defaulted type parameter to a trait [not breaking] .将默认类型参数添加到特征[不破坏]
  • Implementing any non-fundamental trait on an existing type.在现有类型上实现任何非基本特征。
  • Adding any item to an inherent impl .将任何项目添加到固有的impl
  • Changing an undocumented behavior of a function.更改函数的未记录行为。
  • Loosening bounds on an existing type parameter [not breaking] .放松对现有类型参数的限制[不破坏]
  • Adding defaulted type parameters to a type or trait [not breaking] .将默认类型参数添加到类型或特征[不破坏]
  • Generalizing an existing struct or enum field by replacing its type by a new type parameter that defaults to the previous type [breaking until issue 27336 is fixed] .通过用默认为先前类型的新类型参数替换其类型来泛化现有结构或枚举字段[在问题 27336修复之前中断]
  • Introducing a new type parameter to an existing function.向现有函数引入新的类型参数。
  • Generalizing a parameter or the return type of an existing function by replacing the type by a new type parameter that can be instantiated to the previous type.通过用可以实例化为先前类型的新类型参数替换类型来概括现有函数的参数或返回类型。
  • Introducing new lint warnings/errors.引入新的 l​​int 警告/错误。

See the RFC for explanations and examples.有关解释和示例,请参阅RFC

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM