将泛型参数与 impl 中的关联类型匹配
Posted
技术标签:
【中文标题】将泛型参数与 impl 中的关联类型匹配【英文标题】:Matching a generic parameter to an associated type in an impl 【发布时间】:2015-03-30 12:00:39 【问题描述】:我有一个具有关联类型和通用结构的特征::
trait Generator
type Foo;
fn generate(&self) -> Self::Foo;
struct Baz<A, B>
where
A: Generator,
generator: A, // will be some struct implementing Generator, but the exact type will vary
vec: Vec<B>, // Each element will be A::Foo
我想generate
并将其放入我的向量中:
impl<A: Generator, B> Baz<A, B>
fn addFoo(&mut self)
self.vec.push(self.generator.generate());
呃-哦!编译错误:
error[E0308]: mismatched types
--> src/main.rs:16:27
|
16 | self.vec.push(self.generator.generate());
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter, found associated type
|
= note: expected type `B`
found type `<A as Generator>::Foo`
公平地说,我必须向编译器解释B
与A::Foo
相同;让我们试试where
:
impl<A: Generator, B> Baz<A, B>
where
A::Foo = B,
这没有帮助:
error: equality constraints are not yet supported in where clauses (#20041)
--> src/main.rs:16:5
|
16 | A::Foo = B,
| ^^^^^^^^^^
嗯,不等于。也许我可以用冒号运算符来代替?
impl<A: Generator, B> Baz<A, B>
where
B: A::Foo,
error[E0405]: cannot find trait `Foo` in `A`
--> src/main.rs:16:11
|
16 | B: A::Foo,
| ^^^ not found in `A`
不,现在它在抱怨A
。也许我应该说Generator
?
impl<A: Generator, B> Baz<A, B>
where
B: Generator::Foo,
error[E0404]: expected trait, found associated type `Generator::Foo`
--> src/main.rs:16:8
|
16 | B: Generator::Foo,
| ^^^^^^^^^^^^^^ not a trait
干得好,编译器——它不是特性;它是一个关联类型,但这并没有告诉我如何编写与其匹配的 where 子句。
【问题讨论】:
您确定需要生成子类型吗? 【参考方案1】:我必须向编译器解释
B
与A::Foo
是一样的
它有一个特殊的语法:
impl<A, B> Baz<A, B>
where
A: Generator<Foo = B>,
fn add_foo(&mut self)
self.vec.push(self.generator.generate());
【讨论】:
我认为这是他所要求的答案,而不是他想要的答案。谢谢,我不知道这种语法。【参考方案2】:诀窍是只有一个通用参数:
trait Generator
type Foo;
fn generate(&self) -> Self::Foo;
struct Baz<G>
where
G: Generator,
generator: G,
vec: Vec<G::Foo>,
impl<G> Baz<G>
where
G: Generator,
fn add_foo(&mut self)
self.vec.push(self.generator.generate());
由于向量将包含G::Foo
,我们实际上可以这么说。
Rust 风格是snake_case
,所以我更新了它并制作了类型参数G
来帮助读者。
【讨论】:
【参考方案3】:您可以摆脱通用参数B
而不是约束B
,而是直接将A::Foo
作为第二个通用参数传递给Baz
,但我不确定您的实际问题是否与简化的问题相符你展示的例子。
impl<A: Generator> Baz<A, A::Foo>
fn addFoo(&mut self)
self.vec.push(self.generator.generate());
【讨论】:
以上是关于将泛型参数与 impl 中的关联类型匹配的主要内容,如果未能解决你的问题,请参考以下文章