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

相关推荐
NiNg_1_2343 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
Chrikk4 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*4 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue4 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man4 小时前
【go从零单排】go语言中的指针
开发语言·后端·golang
customer086 小时前
【开源免费】基于SpringBoot+Vue.JS周边产品销售网站(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·java-ee·开源
Yaml47 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
老猿讲编程8 小时前
用示例来看C2Rust工具的使用和功能介绍
rust