高级问题陈述
我使用一个通用的声明性宏在许多不同的 crate 中定义了各种通用容器。每个容器看起来都像这样:
struct Container1<T> {
a: T,
b: T,
}
另一方面,我有一个单独的板条箱model
,它具有一个特征ModelTree
,当它们的类型参数实现其他特征时,我想在所有通用容器上实现该特征Model
:
trait ModelTree {
fn integrate_model_tree(self, context: Context);
}
理想情况下应该是
impl<T: Model> ModelTree for Container1<T> {
...
}
[...and similarly for other containers...]
但是,该model
包不能直接依赖于定义容器的所有包(有很多),并且定义容器的包也不能依赖于该model
包。
为了解决这个问题,我考虑从高层次上定义一个通用的 crate common
,它定义了一个“类似于”的特性ModelTree
,让所有容器(例如Container1
)实现这个通用特性,然后ModelTree
对实现这个通用特性的任何东西进行通用实现。然而,unconstrained type parameter
每当我尝试这样做时,我都会不断得到错误。
具体尝试
以下是我在 中尝试的具体操作common
。此游乐场链接包含完整的 MRE。定义一个常见的访客特征:
trait Visitor {
type ItemType;
fn visit(&mut self, item: Self::ItemType);
}
定义“可访问”的特征AcceptVisitor
:
trait AcceptVisitor<V: Visitor<ItemType = Self::ItemType>> {
type ItemType;
fn accept_visitor(self, visitor: V);
}
AcceptVisitor
为所有通用容器实施:
impl<T, V: Visitor<ItemType = T>> AcceptVisitor<V> for Container1<T> {
type ItemType = T;
fn accept_visitor(self, mut visitor: V) {
visitor.visit(self.a);
visitor.visit(self.b);
}
}
在箱子中添加访客垫片model
:
struct ModelVisitor<M: Model> {
context: Context,
phantom: core::marker::PhantomData<M>,
}
impl<M: Model> Visitor for ModelVisitor<M> {
type ItemType = M;
fn visit(&mut self, item: M) {
self.context.add_model(item);
}
}
最后,ModelTree
针对所有实现的类型实现AcceptVisitor
:
impl<
M: Model,
V: Visitor<ItemType = M>,
A: AcceptVisitor<ModelVisitor<M>, ItemType = M>,
> ModelTree for A
{
fn integrate_model_tree(self, context: Context) {
let visitor = ModelVisitor { context, phantom: core::marker::PhantomData };
self.accept_visitor(visitor);
}
}
这就是我得到和的unconstrained type parameter
错误的地方。M
V
问题
有什么方法可以实现我的高级问题陈述?我的具体尝试是否走错了路,还是有办法对其进行调整以使其发挥作用?谢谢!
这听起来很像XY 问题,但如果这确实是你想要做的,你可以将
Visitor
泛型参数从特征移到accept_visitor()
方法。这也是更正确的,因为实现不依赖于单个访问者。