【发布时间】:2025-12-15 06:40:01
【问题描述】:
我对 rust 还很陌生,我正在尝试了解如何最好地创建可重用的共享库组件。我有一个名为 rust-libs 的 github 存储库,它被设置为货物工作区。此 repo 的项目树如下所示:
├── Cargo.lock
├── Cargo.toml
├── describable
│ ├── Cargo.toml
│ └── src
│ ├── describable.rs
│ └── lib.rs
└── health_check
├── Cargo.toml
└── src
├── health_check.rs
└── lib.rs
* Cargo.toml 文件包含:
[workspace]
members = [
"describable",
"health_check"
]
每个成员中的 Cargo.toml 文件只定义了该成员的依赖关系及其版本 - 例如可描述/Cargo.toml:
[package]
name = "lib_describable"
version = "1.0.0"
authors = ["my-name <me@email.com>"]
edition = "2018"
[lib]
name = "lib_describable"
path = "src/lib.rs"
和health_check/Cargo.toml:
[package]
name = "lib_health_check"
version = "1.0.0"
authors = ["my-name <me@email.com>"]
edition = "2018"
[dependencies]
lib_describable = { path = "../describable" }
[lib]
name = "lib_health_check"
path = "src/lib.rs"
请注意,我使用 lib_ 前缀命名库,以避免与其他 rust 库发生任何冲突。
每个工作区成员中的 lib.rs 文件只定义了我要导出的公共模块 - 例如可描述/src/lib.rs:
pub mod describable;
实现在 describable/src/describable.rs 中:
pub trait Describable {
fn describe(&self) -> String;
}
health_check/src/health_check.rs中的实现是:
use lib_describable::describable::Describable;
pub trait HealthCheckable: Describable {
fn check_health(&mut self) -> Result<(), String>;
}
对特定成员进行任何更改时,我总是在其 Cargo.toml 文件中更新其版本号。 CircleCI 用于自动构建这个 repo。如果构建成功,则 CircleCI 作业使用多个 git 标签(工作区中的每个成员一个)标记此 repo,这些标签的格式为 <member-name>_<member-version-from-its-cargo-toml>_<git-short-commit-sha>,例如对于上述两个成员,它可能会用这些标签标记构建:
describable_1.0.0_d2db9ff
health_check_1.0.0_d2db9ff
然后我有一个单独的 git 存储库,其中包含一个使用这些共享库成员构建的 rust 二进制文件。该项目在其 Config.toml 中引用共享库成员如下:
...
[dependencies]
...
lib_describable = { git = "ssh://git@github.com/xxx/rust-libs.git", tag = "describable_1.0.0_d2db9ff" }
lib_health_check = { git = "ssh://git@github.com/xxx/rust-libs.git", tag = "health_check_1.0.0_d2db9ff" }
...
[[bin]]
name = "my-app"
path = "src/bin/main.rs"
xxx 只是我的 github 帐户的混淆名称。该项目中的文件 src/bin/main.rs 包含以下形式的代码:
extern crate lib_describable;
extern crate lib_health_check;
use lib_describable::describable::Describable;
use lib_health_check::health_check::HealthCheckable;
pub trait MyDb: Describable + HealthCheckable {
// some functions defined here that are not important for this issue
}
pub struct MySpecialDb { ... }
impl Describable for MySpecialDb {
fn describe(&self) -> String {
// returns a description of this DB
}
}
impl HealthCheckable for MySpecialDb {
fn check_health(&mut self) -> Result<(), String> {
// performs some health check specific to this DB and returns either Ok(()) if its healthy or Err("...some error message...") if it is unhealthy
}
}
impl MyDb for MySpecialDb { ... }
我发现的问题是 rust 编译器似乎不喜欢 impl HealthCheckable for MySpecialDb 行,并报告以下形式的错误:
the trait bound `...::MySpecialDb: lib_describable::describable::Describable` is not satisfied
the trait `lib_describable::describable::Describable` is not implemented for `...::MySpecialDb`
note: perhaps two different versions of crate `lib_describable` are being used?rustc(E0277)
有什么明显的地方我做错了导致这个错误吗?
【问题讨论】:
-
我很确定 cargo 认为
lib_describable(git)与lib_health_check(git) -> lib_describable(path)不同,您也许可以 override depenedencies 让它们对齐 -
@kmdreko 文档的那部分描述了如何在其他版本的 crate 中打补丁。我也无法让它与我的场景一起使用。如果您能详细说明如何解决此问题,将不胜感激。
标签: rust rust-cargo lib