Подтвердить что ты не робот

Как в Swift указать ограничение типа для перечисления?

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

enum SomeEnum: Int {
  case One, Two, Three
}

class SomeProtocol<E: enum<Int>> { // <- won't compile
    func doSomething(e: E) {
        compute(e.toRaw())
    }
}

Как я могу сделать это в Swift? (Например, я использовал синтаксис F #)

4b9b3361

Ответ 1

enum SomeEnum: Int {
    case One, Two, Three
}

class SomeClass<E: RawRepresentable where E.RawValue == Int>{
    func doSomething(e: E) {
        print(e.rawValue)
    }
}

class SomeEnumClass : SomeClass<SomeEnum> {

}

или непосредственно

class SomeOtherClass{
    func doSomething<E: RawRepresentable where E.RawValue == Int>(e: E) {
        print(e.rawValue)
    }
}

ОБНОВЛЕНИЕ для swift3:

enum SomeEnum: Int {
    case One, Two, Three
}

class SomeClass<E: RawRepresentable> where E.RawValue == Int {
    func doSomething(e: E) {
        print(e.rawValue)
    }
}

class SomeEnumClass : SomeClass<SomeEnum> {

}

соответственно.

class SomeOtherClass{
    func doSomething<E: RawRepresentable>(e: E) where E.RawValue == Int {
        print(e.rawValue)
    }
}

Ответ 2

Пока вы можете переводить перечисления в общий тип без каких-либо ограничений (<T>), невозможно создать ограничения для всех перечислений или всех структур. Все ограничения основаны на интерфейсах (подклассы, протоколы). К сожалению, нет ничего общего между двумя случайными структурами или двумя случайными перечислениями.

Структуры и перечисления не могут наследовать другие структуры/перечисления, поэтому единственные ограничения для перечислений должны основываться на протоколах.

protocol EnumProtocol {
    func method()
}

enum TestEnum : Int, EnumProtocol {
    case A
    case B

    func method() {
    }
}

enum TestEnum2 : Int, EnumProtocol {
    case C

    func method() {
    }
}

class EnumGeneric <T : EnumProtocol> {
    func method(a: T) {
       a.method()
    }
}

let test = EnumGeneric<TestEnum>()
test.method(TestEnum.A)

Также обратите внимание, что все перечисления, "наследующие" от примитивного типа типа Int, соответствуют RawRepresentable, поэтому вы могли

class EnumGeneric <T : RawRepresentable> {
    func method(a: T) {
       println("\(a.toRaw())");
    }
}

но это не будет работать для перечислений, объявленных как enum TestEnum {

Ответ 3

AFAIK, Swift не поддерживает ограничение типа, указанное с перечислениями.

Процитировано из Swift Manual

Синтаксис ограничения строки

Вы записываете ограничения типа, помещая один класс или протоколограничение после имени типа параметров, разделенное двоеточием, как часть списка параметров типа. Основной синтаксис ограничений типа на общей функции показано ниже (хотя синтаксис одинаковый для общих типов):

Строго ограничивается классом или протоколом, если нет некоторых скрытых функций, которые не упоминаются в руководстве. Насколько я тестировал, struct или enum запрещены компилятором.

enum Test1 : Int
{
    case AAA = 0
}

func test1f<T:Test1>(a: Test1) {}       //  error: Inheritance from non-protocol, non-class type 'Test1'

struct Test2
{
    var aaa:Int =   0
}

func test2f<T:Test2>(a: Test2) {}       //  error: Inheritance from non-protocol, non-class type 'Test1'


class Test3
{
}

func test3f<T:Test3>(a: Test3) {}       //  OK