Как я могу отправить stati c для связанного списка, содержащего различные типы, реализующие черту? - PullRequest
2 голосов
/ 05 февраля 2020

У меня есть этот рабочий код:

struct Layer<'a> {
    parent: Option<Box<Layer<'a>>>,
    value: Box<dyn Renderable + 'a>,
}

Я хотел бы иметь версию, используя вместо этого stati c dispatch:

struct Layer<'a, R: Renderable> {
    parent: Option<&'a Layer<'a, /* ? */>>,
    value: R,
}

Тип, заменяющий знак вопроса, реализует Renderable, но это не обязательно R, это может быть, например, T: Renderable. Я хотел бы избежать любого решения, использующего dyn Renderable, для сохранения отправки c.

Тип T: Renderable известен в Layer экземпляре и не изменится.

1 Ответ

2 голосов
/ 06 февраля 2020

TL; DR : невозможно (по крайней мере, без variadi c generics *)

  • Прямо сейчас Layer структура требует 2 generi c параметров: R и 'a.

  • Давайте представим, что мы нашли правильный тип для /* ? */. Давайте назовем его T0.

  • Тогда для структуры Layer потребуется 3 generi c параметров: T0, R и 'a.

  • Затем необходимо предоставить еще один универсальный параметр c для поля parent. Давайте назовем это T1.

  • Тогда Layer структура потребует 4 generi c параметров: T1, T0, R и 'a .

  • Затем необходимо указать еще один универсальный параметр c для поля parent. Давайте назовем это T2.

  • <...>

  • Тогда структура Layer потребует i+2 generi c параметров: Ti, Ti-1, ... T1, T0, R и 'a.
  • Затем необходимо предоставить еще один универсальный параметр c для поля parent. Давайте назовем это Ti+1.
  • Тогда Layer структура потребует i+1+2 generi c параметров: Ti+1, Ti, Ti-1, ... T1, T0, R и 'a.
  • <...>

В конце вы получаете бесконечную рекурсию. Дополнительный параметр generi c для поля parent должен быть определен как часть структуры Layer. Это вызывает введение нового универсального параметра c для Layer. Это вызывает дополнительный параметр generi c для поля parent.

Чтобы разбить рекурсию, дополнительный параметр generi c для parent не должен быть частью определения Layer. Если параметр не является частью определения Layer, мы не можем вычислить размер Layer во время компиляции. Способ ее решения - &dyn или Box.

* Другое возможное решение - variadi c generics , но, похоже, у нас его не будет по крайней мере для следующие несколько месяцев или даже лет.

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