bigywater.tech
Rust · 151

Cargo.toml 依赖解析

Cargo 怎么从一堆版本要求里选出具体版本?两个不兼容的版本能同时存在吗?什么时候解析会失败?锁文件到底钉住了什么?这篇用真实的 crates.io 数据和 cargo 命令回答。

1.0.18
itoa = "1" 解析到的版本(2026-10 的最新 1.x)
2 个版本
重命名后同一个程序里同时存在的 itoa 版本数
failed to select a version
同一大版本内的要求互相冲突时的错误

版本要求的写法

实测 · 本机执行输出
  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 上的最新版本。

同一个 crate 的两个大版本

实测 · 本机执行输出
  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 条件编译。

分步演示

依赖解析
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / rustc 1.98.1(brew)/ cargo 1.98.1;单个文件用 rustc 直接编译,需要依赖时用 cargo(经代理从 crates.io 下载);计时用 std::time::Instant,数字每次运行会有小幅抖动。crates.io 的最新版本为 2026-10 的实测值
    • 没有验证:resolver 版本(2 与 3)对 feature 统一的影响、rust-version(MSRV)感知的解析、git 与 path 依赖的解析、[patch] 与 [replace]、yanked 版本的处理、cargo update 的 -Z minimal-versions
    京ICP备2026067502号-1京公网安备11010502063487号