在 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-outdated
或cargo-tree
)来帮助识别和管理依赖关系。
所以,再也不会用"*"了.坑爹!from刘金,转载请注明原文链接。感谢!