У меня есть экзистенциальный тип , определенный следующим образом:
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>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
детская площадка
При прямом использовании 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]
}
детская площадка
Примечание: Эти примеры создаются во время игры с этой функцией.Я все равно не буду его использовать, пока моя среда IDE не знает о экзистенциальных типах.Кроме того, точный синтаксис может быть изменен.