Ограничить тип generi c быстрым перечислением - PullRequest
1 голос
/ 10 июля 2020

Я хотел бы ограничить тип generi c в Swift выбором различных случаев перечисления.

Ниже пример кода:

enum Test {
  case T1
  case T2
}

enum T1 {
  case one
  case two
}

enum T2 {
  case three
  case four
}


indirect enum Foo<T> {
  case empty
  case cons(T, Foo<T>)
}

let x: Foo<T1> = .cons(.one, .empty)

У меня есть первое Enum который содержит два случая с T1 и T2. Я пытаюсь ограничить тип T в Foo Enum, чтобы иметь доступную коллекцию типов, которыми в моем примере являются T1 и T2. Когда я объявляю x, разрешенные типы: T1 или T2 содержатся в Test, а не другой тип. Следовательно, должны быть разрешены только типы из Enum Test.

Мой вопрос: можно ли использовать Enum для ограничения типа generi c? Если да, то как? Иначе как мне сделать?

1 Ответ

1 голос
/ 10 июля 2020

Метод 1

Согласно комментариям, я думаю, что это то, что вы пытаетесь выполнить sh:

protocol MyEnums {}

enum T1: MyEnums { case one, two }
enum T2: MyEnums { case one, two }
enum T3 { case one, two }

let foo: [MyEnums] = [T1.one, T1.two, T2.one, T2.two]

Массив может содержать только объекты, соответствующие MyEnums протокол.
Обратите внимание, что перечисление T3 не может быть сохранено в foo, потому что оно не соответствует протоколу MyEnums.

Способ 2

Вот еще немного. На самом деле вы можете делать то, о чем просили:

protocol MyEnums {}
enum T1: MyEnums { case one, two }
enum T2: MyEnums { case one, two }
enum T3 { case one, two }
indirect enum Foo<T: MyEnums> {
  case empty
  case cons(T, Foo<T>)
}

Обратите внимание, что generi c это <T: MyEnums>.
Этот код будет делать именно то, что вы хотите. Он может хранить перечисления, соответствующие протоколу MyEnums. Таким образом, вы можете хранить перечисления T1 и T2, если они соответствуют MyEnums, но не T3, потому что это не так.

Итак, вы сможете сделать это:

let x: Foo = .cons(T1.one, .cons(T1.two, .empty))

Однако этот второй метод не позволяет этого:

let x: Foo = .cons(T1.one, .cons(T2.one, .empty))

Я попробую посмотреть, сможем ли мы это сделать ..

Способ 3

Понял !! Это именно то, о чем вы просили:

protocol MyEnums {}
protocol MyEnums1: MyEnums {}

enum T1: MyEnums1 { case one, two }
enum T2: MyEnums1 { case one, two }
enum T3 { case one, two }

indirect enum Foo<T: MyEnums> {
  case empty
  case cons(MyEnums1, Foo<T>)
}

let x: Foo<T1> = .cons(T1.one, .cons(T2.one, .empty))
print(x)

Требовалось 2 протокола, но я, наконец, исправил метод 2. Помните, вы можете вставлять только объекты, соответствующие MyEnums1, поэтому T3 не опция. Отлично!

Это был очень крутой вопрос.

...