我正在尝试创建一个模拟对象以在我的 Rust 项目中进行测试。我遇到一个问题,我想实现一个通用特征,其类型参数还必须实现另一个特征。编译器告诉我通用特征是“密封的”。
这是一个最低限度可重现的示例:
pub trait Trait {
fn trait_test_function();
}
pub trait TraitWithBound<T: Trait> {
fn trait_with_bound_test_function();
}
pub struct StructPassedAsGeneric {
}
pub struct TestStruct {
}
impl Trait for StructPassedAsGeneric {
fn trait_test_function() {
}
}
impl<StructPassedAsGeneric> TraitWithBound<StructPassedAsGeneric> for TestStruct {
fn trait_with_bound_test_function() {
}
}
错误指出:
the trait bound `StructPassedAsGeneric: Trait` is not satisfied
`TraitWithBound` is a "sealed trait", because to implement it you also need to implement `tests::component_tests::graph::commands::teststest::Trait`, which is not accessible; this is usually done to force you to use one of the provided types that already implement it
the following type implements the trait:
tests::component_tests::graph::commands::teststest::StructPassedAsGeneric
我不太明白密封特征是什么意思,特征
TraitWithBound
是公共的,我的StructPassedAsGeneric
实现了Trait
。
密封特征就像编译器所说的那样:它有一个不可访问的超级特征,所以你无法实现它。 你会创造这样的特质:
mod example {
trait Private {}
pub trait Sealed: Private {}
}
struct Type;
impl example::Sealed for Type {}
这会产生与您的问题相同的错误。 在此示例中,
Sealed
是密封特征。 请注意,它具有 Private
作为超级特征,但从 example
模块外部看不到该特征。 因此,特征 example::Sealed
不能在任何 example::Private
不可见的地方实现,因为实现前者也需要实现后者。
正如编译器错误所述,这通常用于防止其他板条箱/模块实现特征,可能是因为该特征包含板条箱的“私有”实现细节,但仍然必须是公共的。