如何使用Swift 2.0枚举来重复自己

时间:2015-07-02 01:58:51

标签: 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(rawValue:what)
    }
}

非常好。我可以说let e = E1(0)并且正确的事情发生了。

现在我想整合重复的代码。我希望Swift 2.0协议扩展允许我这样做 - 在一个位置编写init?(_ what:Int)初始化程序,并在两个枚举中注入/继承它。但是,我还没有找到一种有效的方法。问题是协议扩展不知道采用者拥有 init(rawValue:)初始值设定项,而我还没有办法让它放心。

我怀疑这是因为rawValue初始化程序出现的自动化方式,所以可能无法做任何事情。但也许有人有建议。

3 个答案:

答案 0 :(得分:6)

听起来您正在寻求扩展RawRepresentable协议:

extension RawRepresentable {
    init?(_ what: RawValue) {
        self.init(rawValue: what)
    }
}

任何具有原始类型的枚举都会自动符合RawRepresentable,因此您无法使E1E2符合任何其他协议:

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

答案 1 :(得分:0)

我能够让它发挥作用,就像这样:

table-layout:fixed;

我们使用常规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的协议扩展。

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

答案 2 :(得分:0)

不知道什么可能是错的。有孤立的情况会很好。也许更通用的版本有帮助吗?

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"