https://rustwiki.org/zh-CN/cargo/guide/cargo-toml-vs-cargo-lock.html
以上官方资料中指出
Cargo.toml是从广义上描述你的依赖,并由你编写.Cargo.lock包含有关您的依赖项的确切信息。它由 Cargo 维护,不应手动编辑.
并提出原则:在编写 binary crate 时,应将 Cargo.lock 加入 git 管理并传入仓库;在编写 library crate 时,应避免将 Cargo.lock 加入 git 管理。
我理解,Cargo.toml 使用 semver(Semantic Version 语义版本) 为依赖规定较宽的约束,而 Cargo.lock 是在第一次构建成功后由 cargo 自动记录下的一套确切可行的依赖版本。因为 semver 有时候太宽泛了,同一套 semver 在不同时间下可能有不同的索引结果,所以使用 lock 保证提供一套可行的依赖版本。
binary crate 将 Cargo.lock 加入 git 管理就是为了保证用户可以用这套依赖编译出可用的 二进制文件。
对于 library crate,它作为其他项目的依赖,可能与该项目共同依赖一个第三方 crate,如果两者都用 lock 指定第三方 crate 的版本,而且指定的还是不同版本。那么整个项目内部就会出现对同一个 crate 的不同版本的依赖。这会大大加剧代码的迷惑性,编译器视角下不同的类型,由于隐藏了版本信息,在代码中看起来可能一样。
上面这段话很混乱,举个例子
// 项目 Root,Cargo.toml
[dependencies]
mylib = "0.1"
serde = "1.0" // 检索为 serde = 1.0.201
// mylib,Cargo.toml
[dependencies]
serde = "1.0" // 由 mylib:Cargo.lock 指定为 serde = 1.0.150
// 最终项目 Root 依赖结构
myserver
├── serde 1.0.201
└── mylib
└── serde 1.0.150
// 后续可能报错
expected serde::Value
found serde::Value
// 看着一样,实际来自于不同的版本