Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
798 views
in Technique[技术] by (71.8m points)

rust - Matching a generic parameter to an associated type in an impl

I have a trait with an associated type and a generic struct::

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
}

I want to generate and put it into my vector:

impl<A: Generator, B> Baz<A, B> {
    fn addFoo(&mut self) {
        self.vec.push(self.generator.generate());
    }
}

Uh-oh! Compile error:

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`

Fair enough, I must explain to the compiler that B is the same as A::Foo; let's try with where:

impl<A: Generator, B> Baz<A, B>
where
    A::Foo = B,
{

which doesn't help:

error: equality constraints are not yet supported in where clauses (#20041)
  --> src/main.rs:16:5
   |
16 |     A::Foo = B,
   |     ^^^^^^^^^^

Hmm, no equals. Maybe I can do this with the colon operator instead?

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`

Nope, now it's complaining about A. Maybe I should say 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

Well good work, compiler — it's not a trait; it's an associated type, but that doesn't tell me how to write a where clause that matches it.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I must explain to the compiler that B is the same as A::Foo

There is a special syntax for it:

impl<A, B> Baz<A, B>
where
    A: Generator<Foo = B>,
{
    fn add_foo(&mut self) {
        self.vec.push(self.generator.generate());
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...