簡體   English   中英

將通用參數與impl中的關聯類型匹配

[英]Matching a generic parameter to an associated type in an impl

我有一個關聯類型和通用結構的特征::

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`

很公平,我必須向編譯器解釋BA::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子句。

我必須向編譯器解釋BA::Foo相同

它有一個特殊的語法:

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

訣竅是只有一個通用參數:

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來幫助讀者。

您可以擺脫泛型參數B而不是約束B ,直接將A::Foo作為第二個泛型參數傳遞給Baz ,但我不確定您的實際問題是否與您展示的簡化示例匹配。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM