Enums 如何做';不要用Swift 2.0枚举重复你自己

Enums 如何做';不要用Swift 2.0枚举重复你自己,enums,swift2,Enums,Swift2,我有多个带有原始值的枚举,但我不喜欢每次从原始值初始化一个枚举时都说rawValue:,因此我提供了一个没有外部标签的替代委托初始值设定项: enum E1 : Int { case One, Two init?(_ what:Int) { self.init(rawValue:what) } } enum E2 : Int { case One, Two init?(_ what:Int) { self.init(rawV

我有多个带有原始值的枚举,但我不喜欢每次从原始值初始化一个枚举时都说
rawValue:
,因此我提供了一个没有外部标签的替代委托初始值设定项:

enum E1 : Int {
    case One, Two
    init?(_ what:Int) {
        self.init(rawValue:what)
    }
}
enum E2 : Int {
    case One, Two
    init?(_ what:Int) {
        self.init(rawValue:what)
    }
}
非常好。我可以说
让e=E1(0)
然后正确的事情发生了

现在我想合并重复的代码。我希望Swift 2.0协议扩展能让我做到这一点——在一个地方编写
init?(\uwhat:Int)
初始值设定项,并在两个枚举中注入/继承它。然而,我还没有找到一种有效的方法。问题是,协议扩展不知道采用者将有一个
init(rawValue:)
初始值设定项,我还没有找到一种方法来保证它


我怀疑这是因为
rawValue
初始值设定项的自动生成方式,所以可能什么也做不了。但也许有人有一个建议。

我能让它工作起来,就像这样:

protocol P {
    var rawValue : Int {get}
    init?(rawValue: Int)
}
extension P {
    init?(_ what:Int) {
        self.init(rawValue:what)
    }
}

enum E1 : Int, P {
    case One, Two
}
enum E2 : Int, P {
    case One, Two
}
我们使用常规的
protocol
声明向协议扩展保证我们的采纳者将拥有
init?(rawValue:)


[然而,仍然有一些非常奇怪的事情发生。这段代码在我的一个项目中编译,但在另一个项目中不编译。我认为这与其他代码如何使用P协议有关;如果没有其他代码使用P协议,一切都很好,但是如果其他代码使用P协议,以我没有精确确定的方式,代码无法编译,有一个关于枚举不符合协议的神秘错误。]

不知道会出什么问题。最好有单独的案例。也许更通用的版本会有帮助

protocol BaseRaw {
  typealias T
  var rawValue : T { get }
  init?(rawValue: T)
}

extension BaseRaw {
  init?(_ value: T) {
    self.init(rawValue: value)
  }
}

enum E1 : Int, BaseRaw {
  case One = 1
  case Two = 2
}

enum E2 : String, BaseRaw {
  case One = "1"
  case Two = "2"
}

let e = E1(1)
let e2 = E2("2")

print(e)            // Optional(E1.One)
print(e!.rawValue)  // 1
print(e2)           // Optional(E2.Two)
print(e2!.rawValue) // "2"

听起来您想扩展
RawRepresentable
协议:

extension RawRepresentable {
    init?(_ what: RawValue) {
        self.init(rawValue: what)
    }
}
任何具有原始类型的枚举都会自动符合
rawrrepresentable
,因此您不必使
E1
E2
符合任何额外协议:

enum E1: Int {
    case One = 1, Two
}

enum E2: String {
    case One = "1", Two = "2"
}

let e1 = E1(1)   // .One
let e2 = E2("2") // .Two

也许你的代码中隐藏着另一个名为P的协议。简单但(对我来说)革命性的-我只是没有想到。事实上,它甚至比这更好。我可以说
扩展RawRepresentable where Self:Attribute
,现在我正在做我真正想做的事情,那就是(1)只对某些枚举执行此操作,以及(2)保持将并行枚举包含在公共类型下的能力。