插入符号版本约束在 Rust Cargo 中意味着什么?

What does a caret version constraint mean in Rust Cargo?

我正在实施 Rust Cargo 版本要求。总的来说,我无法理解指定的 插入符号要求 。我找到了 What's the difference between tilde(~) and caret(^) in package.json?,但是这个问题是关于 npm 版本要求的,我不确定它是否与 Rust Cargo 版本要求相同。

https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#caret-requirements,我读到:

Caret requirements allow SemVer compatible updates to a specified version. An update is allowed if the new version number does not modify the left-most non-zero digit in the major, minor, patch grouping. In this case, if we ran cargo update -p time, cargo should update us to version 0.1.13 if it is the latest 0.1.z release, but would not update us to 0.2.0. If instead we had specified the version string as ^1.0, cargo should update to 1.1 if it is the latest 1.y release, but not 2.0. The version 0.0.x is not considered compatible with any other version.

Here are some more examples of caret requirements and the versions that would be allowed with them:

^1.2.3  :=  >=1.2.3, <2.0.0
^1.2    :=  >=1.2.0, <2.0.0
^1      :=  >=1.0.0, <2.0.0
^0.2.3  :=  >=0.2.3, <0.3.0
^0.2    :=  >=0.2.0, <0.3.0
^0.0.3  :=  >=0.0.3, <0.0.4
^0.0    :=  >=0.0.0, <0.1.0
^0      :=  >=0.0.0, <1.0.0

This compatibility convention is different from SemVer in the way it treats versions before 1.0.0. While SemVer says there is no compatibility before 1.0.0, Cargo considers 0.x.y to be compatible with 0.x.z, where y ≥ z and x > 0.

我很困惑

In this case, if we ran cargo update -p time, cargo should update us to version 0.1.13 if it is the latest 0.1.z release, but would not update us to 0.2.0.

这是什么版本要求?它似乎被排除在句子之外。它继续提到一个看似缺失的插入符号版本要求:

If instead we had specified the version string as ^1.0, cargo should update to 1.1 if it is the latest 1.y release, but not 2.0.

其中它指的是 >1.0 作为版本字符串(我在前面的句子中遗漏了)。

如果我剖析这些例子,我的推理如下:

^1.2.3  :=  >=1.2.3, <2.0.0 // same as >=1.2.3 AND 1.*
^1.2    :=  >=1.2.0, <2.0.0 // same as >=1.2 AND 1.*, which condenses into 1.2.*
^1      :=  >=1.0.0, <2.0.0 // same as 1.*
^0.2.3  :=  >=0.2.3, <0.3.0 // same as >=0.2.3 AND 0.2.*
^0.2    :=  >=0.2.0, <0.3.0 // same as 0.2.*, which condenses into 0.2.*
^0.0.3  :=  >=0.0.3, <0.0.4 // huh
^0.0    :=  >=0.0.0, <0.1.0 // same as >=0.0.0 AND 0.0.*
^0      :=  >=0.0.0, <1.0.0 // same as >=0.0.0 AND 0.*, which condenses into 0.*

因此,除了我对第 6 个示例 (^0.0.3) 的理解外,我的结论是插入符版本要求与通配符版本要求完全相同,除非指定了 PATCH,其中通配符版本要求与>= {version}(等于或晚于)比较版本要求。

这个理解对吗?为什么是例6?

与 npm 不同,默认版本要求范围确实是插入符要求!这在 Cargo reference on "specifying dependencies" 中说明,就在问题中链接的部分之前。

The string "0.1.12" is a semver version requirement. Since this string does not have any operators in it, it is interpreted the same way as if we had specified "^0.1.12", which is called a caret requirement.

因此,以下两个依赖规范是等价的。

time = "0.1.12"
time = "^0.1.12"

顺便说一下,这是文档其余部分中提到的要求。 time 的更新可以引入高于 0.1.12 的版本,但绝不会引入 0.2.0 或更高版本。

另请参阅: