如何在Swift中指定类型约束为枚举?

时间:2014-06-04 07:38:26

标签: enums swift

我想指定一个类型约束,该类型应该是原始值枚举:

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

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

我怎样才能在Swift中做到这一点? (我使用了F#语法)

3 个答案:

答案 0 :(得分:57)

let dictionary = [ for i in 1..4 -> i, true ] |> Map.ofSeq 

或直接

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> {

}

swift3的更新:

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

RESP。

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> {

}

答案 1 :(得分:11)

虽然您可以将枚举放入没有约束的通用类型(<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 {

的枚举不起作用

答案 2 :(得分:4)

AFAIK,Swift不支持使用枚举指定类型约束。

引自Swift Manual

  

键入约束语法

     

您可以通过放置单个类或协议来编写类型约束   类型参数名称后面的约束,用冒号分隔,如   类型参数列表的一部分。类型约束的基本语法   下面显示了一个泛型函数(尽管语法是相同的)   对于泛型类型):

严格限于类或协议,除非手册中未提及某些隐藏功能。据我测试,structenum都是编译器禁止的。

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