【问题标题】:How in Swift specify type constraint to be enum?如何在 Swift 中指定类型约束为枚举?
【发布时间】:2014-07-24 18:16:42
【问题描述】:

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

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

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

如何在 Swift 中做到这一点? (例如,我使用了 F# 语法)

【问题讨论】:

    标签: enums swift


    【解决方案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)
        }
    }
    

    【讨论】:

    • @JMI:你救了我!我快疯了:D
    • 我正在使用它,我想定义类似var dict:[E:MyType] 的东西,但是 Xcode 8.2 抱怨 E 不符合 Hashable。想法?
    • 好的——我想我现在明白了。在我的情况下,类声明需要以:class MyClass&lt;E: RawRepresentable&gt; where E: Hashable {
    • 虽然这可能行得通,但它确实感觉像是围绕核心 Swift 设计原则的终结
    【解决方案2】:

    虽然您可以将枚举放入没有约束的泛型类型 (&lt;T&gt;),但无法为所有枚举或所有结构创建约束。所有约束都基于接口(子类化、协议)。不幸的是,两个随机结构或两个随机枚举之间没有任何共同点。

    结构和枚举不能从其他结构/枚举继承,因此枚举的唯一约束必须基于协议。

    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

      类型约束语法

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

      除非存在手册中未提及的某些隐藏功能,否则仅限于类或协议。据我测试,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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多