Cargo 怎么从一堆版本要求里选出具体版本?两个不兼容的版本能同时存在吗?什么时候解析会失败?锁文件到底钉住了什么?这篇用真实的 crates.io 数据和 cargo 命令回答。
itoa = "1" 1 的最新版本 → 解析为 ['1.0.18'] itoa = "1.0" ^1.0 → 解析为 ['1.0.18'] itoa = "~1.0.5" ~1.0.5 = >=1.0.5, <1.1.0 → 解析为 ['1.0.18'] itoa = "=1.0.9" 精确版本 → 解析为 ['1.0.9'] itoa = "0.4" ^0.4(0.x 里次版本号是不兼容边界) → 解析为 ['0.4.8'] itoa = ">=1.0.2, <1.0.8" 范围 → 解析为 ['1.0.7']
Cargo.lock 的作用见Cargo.lock 的作用;workspace 里统一依赖见Workspace 依赖管理。结果依赖当天 crates.io 上的最新版本。
cargo tree:
Updating crates.io index
Locking 2 packages to latest Rust 1.98.1 compatible versions
Adding itoa v0.4.8 (available: v1.0.18)
u151b v0.1.0 (<实验目录>/proj/u151b)
├── itoa v0.4.8
└── itoa v1.0.18
cargo tree -d(重复的 crate):
itoa v0.4.8
└── u151b v0.1.0 (<实验目录>/proj/u151b)
itoa v1.0.18
└── u151b v0.1.0 (<实验目录>/proj/u151b)
运行(两个版本在同一个程序里都可用): 12345 | 67890 Updating crates.io index
error: failed to select a version for `itoa`.
... required by package `right v0.1.0 (<实验目录>/proj/u151c/right)`
... which satisfies path dependency `right` of package `app v0.1.0 (<实验目录>/proj/u151c/app)`
versions that meet the requirements `>=1.0.10` are: 1.0.18, 1.0.17, 1.0.16, 1.0.15, 1.0.14, 1.0.13, 1.0.12, 1.0.11, 1.0.10
all possible versions conflict with previously selected packages
previously selected package `itoa v1.0.5`
... which satisfies dependency `itoa = "=1.0.5"` of package `left v0.1.0 (<实验目录>/proj/u151c/left)`generate-lockfile 得到 itoa 1.0.18;cargo update -p itoa --precise 1.0.5 之后 Cargo.lock 里是 1.0.5(满足 "1" 的要求,可以回退) 之后正常 cargo build:Cargo.lock 里仍是 1.0.5(即使 crates.io 上有更新的 1.0.18,锁文件钉住的版本不会被自动升级) cargo update -p itoa 之后回到 1.0.18;Cargo.toml 没有改动:1 处 itoa 声明 --precise 到不满足 "1" 的 0.4.8: ['error: failed to select a version for the requirement `itoa = "^1"`']
feature 对依赖图的影响见Feature Flag 条件编译。