Преодоление псевдонима типа «…» ссылается на себя - PullRequest
2 голосов
/ 05 марта 2020

Фон

У меня есть перечисление, которое, упрощенно, выглядит так:

enum Container<T> {
  case a(T)
  case b(T)
  case c
}

Я хочу иметь возможность создать его с несколькими различными типами для обобщенного c и используйте для этого typealias:

typealias IntContainer = Container<Int>
typealias FloatContainer = Container<Float>

Задача

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

typealias CyclicContainer = Container<CyclicContainer>

Swift сообщает об этом с ошибкой компиляции:

Псевдоним типа 'CyclicContainer' ссылается на себя

… Эта ошибка все еще появляется, когда я изменяю объявление Container на:

indirect enum Container<T>

Это немного раздражает, потому что это будет полезным и компилирующим Swift :

indirect enum CyclicContainer {
  case a(CyclicContainer)
  case b(CyclicContainer)
  case c
}

Обходной путь 1

Для этого есть обходной путь. Я могу объявить, например:

indirect enum CyclicContainer {
   case container(Container<CyclicContainer>)
}

… Однако, это становится неудобным для кратких описаний экземпляра CyclicContainer:

let cyclicContainer: CyclicContainer = .container(.a(.container(.b(.container(.c)))))

Вместо просто:

let cyclicContainer: CyclicContainer = .a(.b(.c))

Обходной путь 2

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

indirect enum CyclicContainer {
    case a(CyclicContainer)
    case b(CyclicContainer)
    case c
}

Однако мне потребуется: создать функции для преобразования от CyclicContainer до Container; повторно реализовать различные функции-члены, которые существуют в Container<T>; и сохраняйте эти два типа в будущем c, если я добавлю новый случай или изменим имя случая.

Это не очень сложно, и к этому я склоняюсь. Но, кажется, стыдно делать это, когда Swift может справиться с indirect enum совершенно счастливо, но не тогда, когда это вызвано созданием аргумента generi c в перечислении.

Вопрос

Есть ли лучший способ?

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