为什么存在类型需要通用类型而不是关联类型?

时间:2019-04-24 09:25:31

标签: generics rust existential-type associated-types

我有一个existential type定义如下:

trait Collection {
    type Element;
}
impl<T> Collection for Vec<T> {
    type Element = T;
}

existential type Existential<T>: Collection<Element = T>;

一个函数,该函数采用实现具有关联类型的特征的类型,并返回该类型。 这段代码为什么起作用:

fn return_existential<I, T>(iter: I) -> Existential<T>
where
    I: IntoIterator<Item = T>,
    I::Item: Collection,
{
    let item = iter.into_iter().next().unwrap();
    vec![item]
}

playgroud

这不是:

fn return_existential<I>(iter: I) -> Existential<I::Item>
where
    I: IntoIterator,
    I::Item: Collection,
{
    let item = iter.into_iter().next().unwrap();
    vec![item]
}
error: type parameter `I` is part of concrete type but not used in parameter list for existential type
  --> src/lib.rs:16:1
   |
16 | / {
17 | |     let item = iter.into_iter().next().unwrap();
18 | |     vec![item]
19 | | }
   | |_^

error: defining existential type use does not fully define existential type
  --> src/lib.rs:12:1
   |
12 | / fn return_existential<I>(iter: I) -> Existential<I::Item>
13 | | where
14 | |     I: IntoIterator,
15 | |     I::Item: Collection,
...  |
18 | |     vec![item]
19 | | }
   | |_^

error: could not find defining uses
  --> src/lib.rs:10:1
   |
10 | existential type Existential<T>: Collection<Element = T>;
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

playground

直接使用Vec时,效果很好:

fn return_existential<I>(iter: I) -> Vec<I::Item>
where
    I: IntoIterator,
    I::Item: Collection,
{
    let item = iter.into_iter().next().unwrap();
    vec![item]
}

playground

注意:这些示例是在使用此功能时构建的。只要我的IDE不知道存在类型,我就不会使用它。此外,确切的语法可能会更改。

0 个答案:

没有答案