Как опустить параметр типа верхнего уровня в общих / вложенных структурах? - PullRequest
0 голосов
/ 02 сентября 2018

Я хочу создать структуру базы данных, которую я могу использовать следующим образом:

let c: Database<Disk<u8>> = ...

Однако, когда я наивно это реализую:

trait Element {}

trait Storage<E> where E: Element {}

struct Disk<E> where E: Element {
    data: E,
}  

impl<E> Storage<E> for Disk<E> where E: Element {}

struct Database<S>
where
    S: Storage<E>, 
    E: Element,
{
    storage: S,
}

Я получаю ошибку, что E неизвестно:

error[E0412]: cannot find type `E` in this scope
  --> src/main.rs:30:16
   |
30 |     S: Storage<E>, // <-- Error: E not found.
   |                ^ did you mean `Eq`?

Детская площадка

Я мог бы явно сделать E явным, например:

struct DatabaseUgly<S, E>
where
    S: Storage<E>,
    E: Element 

Но тогда мне придется повторить тип элемента:

let c: DatabaseUgly<Disk<u8>, u8> = ...

Как мне заставить Database работать?


Примечание: поскольку это происходило более одного раза, не редактируйте заголовок моего вопроса, не обсудив его в первую очередь. Возможно, я не использовал правильную терминологию, но если бы я знал, что именно искать, я бы, наверное, не спрашивал / не искал таким образом.

1 Ответ

0 голосов
/ 02 сентября 2018

Простым решением является использование связанного типа в признаке, а не универсального:

trait Element {}

trait Storage { // not generic
    type Element: Element;
}

struct Disk<E>
where
    E: Element,
{
    data: E,
}

impl<E> Storage for Disk<E>
where
    E: Element,
{
    type Element = E;
}

struct Database<S>
where
    S: Storage,
    S::Element: Element,
{
    storage: S,
}

( ссылка на игровую площадку )

См. Также Когда целесообразно использовать связанный тип по сравнению с универсальным типом?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...