以下示例是我能想到的最简单的示例,旨在说明我正在努力实现的目标:
pub trait Recipient {
fn receive(&self, number: i32);
}
pub trait RecipientCatalog<R: Recipient> {
fn lookup<'a>(&self, recipient_index: usize) -> &'a R;
}
pub struct NumberDispatch<C>
where C: RecipientCatalog<R> {
catalog: C
}
impl<C> NumberDispatch<C>
where C: RecipientCatalog<R> {
pub fn dispatch(&self, number: i32) {
let recipient_index = 0; // Would be lookup logic
self.catalog.lookup(recipient_index).receive(number);
}
}
在示例中,NumberDispatch 应该能够将给定的号码分派给某个已解析的 Recipient 实现(查找逻辑对于该示例并不重要)。但是,由于未定义类型“R”,因此该代码无法按原样编译。但我不知道如何定义 NumberDispatch 结构中的 R 是什么。
这个想法是,API 用户将提供某种类型的 RecipientCatalog,它提供对实现 Recipient 特征的引用。然后 NumberDispatch 应该能够通过在提供的 RecipientCatalog 实现中查找号码来将号码传递给某个已解析的收件人。
这意味着 NumberDispatch 定义了一个受限于 RecipientCatalog 实现的泛型。但由于 RecipientCatalog 还定义了受 Recipient 特征约束的通用类型,因此我无法找到在 NumberDispatch 结构中定义它的方法。
有谁知道是否可以以及如何做这样的事情?
(编辑:忘记了特征中的&self)
将其设为关联类型,如果它只能是一种类型:
pub trait Recipient {
fn receive(&self, number: i32);
}
pub trait RecipientCatalog {
type Recipient: Recipient;
fn lookup(&self, recipient_index: usize) -> &Self::Recipient;
}
pub struct NumberDispatch<C> {
catalog: C,
}
impl<C> NumberDispatch<C>
where
C: RecipientCatalog,
{
pub fn dispatch(&self, number: i32) {
let recipient_index = 0; // Would be lookup logic
self.catalog.lookup(recipient_index).receive(number);
}
}
我还删除了对结构的约束,因为你不应该把它们放在那里。