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

相关推荐
千|寻15 分钟前
【画江湖】langchain4j - Java1.8下spring boot集成ollama调用本地大模型之问道系列(第一问)
java·spring boot·后端·langchain
程序员岳焱29 分钟前
Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解
后端·sql·mysql
龚思凯35 分钟前
Node.js 模块导入语法变革全解析
后端·node.js
天行健的回响38 分钟前
枚举在实际开发中的使用小Tips
后端
wuhunyu43 分钟前
基于 langchain4j 的简易 RAG
后端
techzhi43 分钟前
SeaweedFS S3 Spring Boot Starter
java·spring boot·后端
写bug写bug2 小时前
手把手教你使用JConsole
java·后端·程序员
苏三说技术2 小时前
给你1亿的Redis key,如何高效统计?
后端
JohnYan2 小时前
工作笔记- 记一次MySQL数据移植表空间错误排除
数据库·后端·mysql
程序员清风3 小时前
阿里二面:Kafka 消费者消费消息慢(10 多分钟),会对 Kafka 有什么影响?
java·后端·面试