Rust:避坑篇:坑爹的 "*"

在 Rust 项目中使用 crate = "*" 作为 Cargo.toml 文件中的依赖项声明是一种指定依赖关系的方式,意图告诉 Cargo 包管理器自动选择 crate 库的最新版本。这种做法看似简便,但实际上可能带来一些风险和复杂性,特别是在项目依赖管理和版本兼容性方面。

在今天以前,我都认为这是一个好用且实用的写法,因为它可以始终选择最新版本,并且在我的工作中广泛使用,但是!在今天我彻底的改变了我的想法,并直接抛弃了这种习惯。并打算永不用"*"为什么?请往下看

报错,版本不对:

今天开心的写着业务,写到用bb8创建redis连接池:

rust 复制代码
use crate::config::CFG;
use bb8::Pool;
use bb8_redis::{bb8, RedisConnectionManager};
use tokio::sync::OnceCell;
pub static REDIS: OnceCell<Pool<RedisConnectionManager>> = OnceCell::const_new();

pub async fn init_redis_pool() {
    let manager = RedisConnectionManager::new(CFG.redis.redis_url.clone()).unwrap();

    let pool = Pool::builder()
        .build(manager)
        .await
        .expect("db connect failed");

    REDIS.get_or_init(|| async { pool }).await;
}

然后运行项目,报错!

bush 复制代码
thread 'main' panicked at /home/pomelo/.cargo/registry/src/mirrors.ustc.edu.cn-
12df342d903acd47/tokio-0.3.7/src/time/driver/handle.rs:50:18: 
there is no timer running, must be called from the context of a Tokio 0.3.x runtime note: run 
with `RUST_BACKTRACE=1` environment variable to display a backtrace

嗯?

tokio-0.3.7?这什么东西,谁给我从清朝墓里刨出来的?

版本不对,那就检查下吧toml文件吧。

toml 复制代码
tokio = { version = "1", features = ["full"] }
bb8 = "*" 

我tokio异步运行时版本没错呀? bb8也是最新的呀? 0.3.7是哪儿来的?

难道bb8最新版本这么low?不应该啊,前两天还在更新这个库,怎么可能异步运行时版本这么低?不放心的我还是去docs.rs查了一下,

bb8最新版本0.8.1,又去github上面看了下源码:作者也在用tokio 1的版本呀?那说明运行时没问题,那为什么我的不支持呢?

除非我的bb8不是最新版本0.8.1

得,看看我的什么版本直接去cargo.lock文件里看一下不就行了

lock 复制代码
 
[[package]] 
name = "bb8" 
version = "0.6.2" 
source = "registry+https://github.com/rust-lang/crates.io-index" 
checksum = "486f2c0824c803d4e77f7cb915c9f0413a772f1dcef3ccf304bd39fa099c781a" 
dependencies = [ 
"async-trait", 
"futures-channel", 
"futures-util", 
"parking_lot 0.11.2", 
"tokio 0.3.7", 
]

还真是这样,那这更不对了,我明明用的最新版本,怎么成了0.6.2了?不对,这个"*" 有问题

坑爹的"*"

我又去查了下"*"

Cargo.toml 文件中使用 bb8 = "*" 时,理论上 Cargo 应该解析并使用最新的 bb8 版本。然而,如果项目中存在其他依赖项,它们可能会间接地引入 bb8 的一个较旧版本,或者项目可能有某些限制,导致 Cargo 无法使用最新版本。这种情况下,Cargo 会尝试找到一个满足所有依赖项版本要求的解决方案,有时这可能是一个较旧的版本。

  • 不兼容的风险:自动选择最新版本可能导致不兼容的问题。新版本可能引入了破坏性变更(breaking changes),这可能会影响项目。
  • 依赖项的间接影响 :如果项目中其他依赖项也依赖于 bb8(直接或间接),它们可能指定了不同的版本要求,这可能导致 Cargo 解析为较旧的 bb8 版本,而不是最新的。

也就是说

在我的项目中,虽然指定了 bb8 = "*",意在使用最新版的 bb8,但 Cargo 实际上解析并使用了版本 0.6.2。这是因为的项目或其它依赖项存在某些限制或要求,导致 Cargo 无法使用 bb8 的最新版本。特别是在项目中使用了 Tokio 1.x 版本的情况下,bb8 0.6.2 版本依赖于不兼容的旧版 Tokio(0.3.7),导致了版本冲突和运行时错误。

明白以后,建议和最佳实践

  • 明确指定版本 :尽量指定依赖项的具体版本号(例如 bb8 = "0.7.0"),这可以提高项目的稳定性和可预测性。
  • 定期更新依赖:定期检查和更新依赖项,确保使用的是支持和兼容的版本。
  • 避免使用"*" :避免使用 * 来指定依赖项版本,因为这可能导致意外的版本冲突和不兼容问题。
  • 依赖管理工具 :使用依赖管理工具(如 cargo-outdatedcargo-tree)来帮助识别和管理依赖关系。

所以,再也不会用"*"了.坑爹!from刘金,转载请注明原文链接。感谢!

相关推荐
martinzh2 小时前
Spring AI 项目介绍
后端
susnm2 小时前
Dioxus 与数据库协作
前端·rust
前端付豪2 小时前
20、用 Python + API 打造终端天气预报工具(支持城市查询、天气图标、美化输出🧊
后端·python
爱学习的小学渣2 小时前
关系型数据库
后端
武子康2 小时前
大数据-33 HBase 整体架构 HMaster HRegion
大数据·后端·hbase
前端付豪2 小时前
19、用 Python + OpenAI 构建一个命令行 AI 问答助手
后端·python
凌览2 小时前
斩获 27k Star,一款开源的网站统计工具
前端·javascript·后端
全栈凯哥2 小时前
02.SpringBoot常用Utils工具类详解
java·spring boot·后端
狂师2 小时前
啥是AI Agent!2025年值得推荐入坑AI Agent的五大工具框架!(新手科普篇)
人工智能·后端·程序员
羊八井2 小时前
类型、分类定义时使用 type 还是 kind ?
rust·typescript·代码规范