如何使枚举符合Swift中的协议?

Adr*_*wne 90 enums swift swift-protocols

Swift文档说,结构枚举都可以符合协议,我可以达到一致的程度.但我无法让enum表现得像结构示例:

protocol ExampleProtocol {
    var simpleDescription: String { get set }
    mutating func adjust()
}

class SimpleClass: ExampleProtocol {
    var simpleDescription: String = "A very simple class."
    var anotherProperty: Int = 69105

    func adjust() {
        simpleDescription += " Now 100% adjusted."
    }
}

var a = SimpleClass()
a.adjust()
let aDescription = a.simpleDescription

struct SimpleStructure: ExampleProtocol {
    var simpleDescription: String = "A simple structure"

    mutating func adjust() {
        simpleDescription += " (adjusted)"
    }
}

var b = SimpleStructure()
b.adjust()
let bDescription = b.simpleDescription

enum SimpleEnum: ExampleProtocol {
    case Base

    var simpleDescription: String {
        get {
            return "A Simple Enum"
        }
        set {
            newValue
        }
    }

    mutating func adjust() {
        self.simpleDescription += ", adjusted"
    }
}

var c = SimpleEnum.Base
c.adjust()
let cDescription = c.simpleDescription
Run Code Online (Sandbox Code Playgroud)

我还没弄清楚如何通过simpleDescription调用来改变adjust().我的例子显然不会这样做因为getter有一个硬编码的值,但是如何设置一个值simpleDescription仍然符合ExampleProtocol

小智 147

这是我的尝试:

protocol ExampleProtocol {
    var simpleDescription: String { get }
    mutating func adjust()
}

enum ExampleEnum : ExampleProtocol {
    case Base, Adjusted

    var simpleDescription: String {
        return self.getDescription()
    }

    func getDescription() -> String {
        switch self {
        case .Base:
            return "A simple description of enum"
        case .Adjusted:
            return "Adjusted description of enum"
        }
    }

    mutating func adjust() {
        self = ExampleEnum.Adjusted
    }
}

var c = ExampleEnum.Base
c.adjust()
let cDescription = c.simpleDescription
Run Code Online (Sandbox Code Playgroud)


Zed*_*nem 44

这是我的看法.

因为这是一个enum而不是一个class,你必须考虑不同的(TM):当你的enum变化的"状态"时,你的描述必须改变(正如@ hu-qiang指出的那样).

enum SimpleEnumeration: ExampleProtocol {
  case Basic, Adjusted

  var description: String {
    switch self {
    case .Basic:
      return "A simple Enumeration"
    case .Adjusted:
      return "A simple Enumeration [adjusted]"
    }
  }

  mutating func adjust()  {
    self = .Adjusted
  }
}

var c = SimpleEnumeration.Basic
c.description
c.adjust()
c.description
Run Code Online (Sandbox Code Playgroud)

希望有所帮助.

  • 这个答案比公认的答案更好,更简洁. (4认同)
  • 只需注意,您可以删除SimpleEnumeration.Adjusted并替换为".Adjusted".如果枚举的名称发生了变化,那么重构就不那么重要了. (2认同)

Jac*_*mes 11

这是另一种方法,只使用从巡回赛获得的知识,直到那一点*

enum SimpleEnumeration: String, ExampleProtocol {
    case Basic = "A simple enumeration", Adjusted = "A simple enumeration (adjusted)"

    var simpleDescription: String {
        get {
            return self.toRaw()
        }
    }

    mutating func adjust() {
        self = .Adjusted
    }
}

var c = SimpleEnumeration.Basic
c.adjust()
let cDescription = c.simpleDescription
Run Code Online (Sandbox Code Playgroud)

如果你想adjust()充当一个切换(虽然没有什么可以暗示这种情况),使用:

mutating func adjust() {
    switch self {
    case .Basic:
        self = .Adjusted
    default:
        self = .Basic
    }
}
Run Code Online (Sandbox Code Playgroud)

*(虽然它没有明确提到如何指定返回类型协议)

  • 我认为这种方法可能是最好的一种.快速更新是simpleDescription应该返回self.rawValue (2认同)

Dio*_*ves 7

这是一个不改变当前枚举值的解决方案,而是改变它们的实例值(以防它对任何人都有用).

enum ProtoEnumeration : ExampleProtocol {
    case One(String)
    case Two(String)

    var simpleDescription: String {
        get {
            switch self {
            case let .One(desc):
                return desc
            case let .Two(desc):
                return desc
            }
        }
    }
    mutating func adjust() {
        switch self {
        case let .One(desc):
            self = .One(desc + ", adjusted 1")
        case let .Two(desc):
            self = .Two(desc + ", adjusted 2")
        }
    }
}

var p = ProtoEnumeration.One("test")
p.simpleDescription
p.adjust()
p.simpleDescription
Run Code Online (Sandbox Code Playgroud)