为什么添加 byteorder 会使 Cargo 降级 mysql 到 8.0.0 版本?

Why does adding byteorder make Cargo downgrade mysql to version 8.0.0?

我用 Rust 开发一个项目已有一段时间了。几天前,我 运行 cargo update 和我的一大堆依赖项都被降级了,我一直无法弄清楚为什么。我创建了一个新项目,发现如果 Cargo.toml 中的依赖项只是

[dependencies]
mysql = "*"

如我所料,它使用最新的 mysql (11.3.0) 构建。如果我添加

byteorder = "1"

然后 运行 cargo clean/cargo updatemysql 降级到 8.0.0。

任何帮助弄清楚 byteorder 依赖性导致 Cargo 降级 mysql 或如何阻止它这样做的帮助将不胜感激。

how to stop it from doing so

这是简单的部分:不要使用通配符版本。您的代码与 字面意思 曾经发布的任何版本的箱子一起工作的机会平均为零。

why the byteorder dependency is making Cargo downgrade mysql

这实际上真的很难回答。选择依赖项 。由于大多数程序员不在乎等待那么久,因此每个依赖项管理器中都有试探法、偏好和捷径。我不知道 Cargo 算法的所有细微差别,所以大部分都是有根据的猜测或调查。

您已经通过说 mysql = "*" 告诉 Cargo "I don't care what version mysql to use"。 Cargo 现在可以自由使用它想要的任何版本,这是一个非常灵活的要求。

在这种情况下,mysql 11.3.0 has chosen to require byteorder = "~1.0"。那 not 允许字节顺序 1.1.0。依赖项解析的某些方面看到了这一点,并表示最好让您的 crate 具有字节顺序的 1.1.0 版本,即使这意味着 mysql 需要降级为非冲突版本。重要的是版本 8.0.0 是最后一个只需要字节序 0.5.3 的版本。

如果您尝试将两者都强制为当前版本,您将看到:

error: failed to select a version for `byteorder` (required by `mysql`):
all possible versions conflict with previously selected versions of `byteorder`
  version 1.1.0 in use by byteorder v1.1.0
  possible versions to select: 1.0.0

但是,您可以获得几乎完全更新:

[dependencies]
mysql = "11.3.0"
byteorder = "1.0.0"

我不完全确定为什么 Cargo 允许您同时拥有版本 1.1 和 0.5 而不是 1.1 和 1.0,但我的猜测是启发式算法只有一个给定的语义主要版本板条箱。

Cargo 的未来增强可能会引入 "public" and "private" dependencies 的概念,这可能会改变解析算法并使这种情况更好,因为字节顺序可能是 mysql 的内部依赖项,而您不需要匹配。