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刘金,转载请注明原文链接。感谢!

相关推荐
明月_清风6 小时前
加密解密系统完全指南:原理剖析与 Go 实践
后端
小江的记录本7 小时前
【JVM虚拟机】垃圾回收GC:垃圾收集器:CMS:核心原理、回收流程、优缺点、废弃原因(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·spring·面试·maven
冬奇Lab7 小时前
每日一个开源项目(第105篇):Twenty - 跳出 Salesforce 的圈套,定义现代开源 CRM
前端·后端·开源
ServBay9 小时前
月之暗面 Kimi Code 0.4.0 发布,终端 AI 编码助手全面采用 TypeScript,实现毫秒级启动
后端·aigc·ai编程
小江的记录本9 小时前
【JVM虚拟机】垃圾回收GC:垃圾回收算法:标记-清除、标记-复制、标记-整理、分代收集(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·算法·安全·面试
小江的记录本9 小时前
【JVM虚拟机】垃圾回收GC:垃圾收集器:G1:Region分区、Mixed GC、回收流程、适用场景(高频)(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·spring·spring cloud·面试
欧雷殿10 小时前
从「吸引子引导工程」看我的「一人公司」实践
前端·人工智能·后端
卷无止境10 小时前
用一个电影院售票厅,把 SimPy 的条件事件讲透
后端
日月云棠11 小时前
9 Double 与 Float —— IEEE 754 浮点数在 Java 中的实现
java·后端