How to make an enum conform to a protocol in Swift?

前端 未结 15 1230
终归单人心
终归单人心 2020-12-22 16:32

Swift documentation says that classes, structs, and enums can all conform to protocols, and I can get to a point where they all conform. But I can

相关标签:
15条回答
  • 2020-12-22 17:07

    I was thinking that the goal is simply to retain state and use a description to make the current state easier to read:

    enum SimpleEnum: ExampleProtocol {
    
        case Default, Adjusted
    
        init() {
            self = .Default
        }
    
        var simpleDescription: String { get { return "\(self) Value" }}
    
        mutating func adjust() {
            self = .Adjusted
        }
    }
    
    var simpleEnum = SimpleEnum()
    simpleEnum.adjust()
    let adjustedSimple = simpleEnum.simpleDescript
    
    0 讨论(0)
  • 2020-12-22 17:12

    Another option is for adjust() to flip between cases as follows:

    enum SimpleEnum: ExampleProtocol {
        case Foo, Bar
    
        var simpleDescription: String {
        get {
            let value = self == .Foo
                ? "Foo"
                : "Bar"
            return "A simple \(value) enum."
        }
        }
    
        mutating func adjust() {
            self = self == .Foo
                ? .Bar
                : .Foo
        }
    }
    
    0 讨论(0)
  • 2020-12-22 17:12

    Here's building on Jack's answer:

    protocol ICanWalk {
        var description: String { get }
        mutating func stepIt()
    }
    
    enum TwoStepsForwardThreeStepsBack: Int, ICanWalk {
        case Base = 0, Step1, Step2
    
        var description: String {
            return "Step \(self.rawValue)"
        }
    
        mutating func stepIt() {
            if let nextStep = TwoStepsForwardThreeStepsBack( rawValue: self.rawValue + 1 ) {
                // going forward.
                self = nextStep
            } else {
                // back to the base.
                self = TwoStepsForwardThreeStepsBack.Base
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-22 17:13

    how about this

    enum SimpleEnum : ExampleProtocol {
        case Desc(String)
        init() {
            self = Desc("a simple enum")
        }
        var simpleDescription:String {
            get {
                return (Mirror(reflecting: self).children.first!.value as? String)!
            }
        }
        mutating func adjust() {
            self = SimpleEnum.Desc(self.desc + " adjusted")
        }
    }
    var e = SimpleEnum()
    e.simpleDescription    # => "a simple enum"
    e.adjust()
    e.simpleDescription    # => "a simple enum adjusted"
    
    0 讨论(0)
  • 2020-12-22 17:15

    This experiment threw me off too, due to the previous SimpleClass and SimpleStructure examples showing the property simpleDescription being modified internally, which caused me to think that I needed to do the same thing. After looking over the other answers posted here and reading the official Apple Swift 2.1 documentation, I came up with this:

    protocol ExampleProtocol {
         var simpleDescription: String { get }
         mutating func adjust()
    }
    
    enum SimpleEnum: ExampleProtocol {
        case Simple
        case Adjusted
    
        var simpleDescription: String {
            switch self {
            case .Simple:
                return "A simple enumeration"
            case .Adjusted:
                return "A simple enumeration somewhat changed."
            }
        }
    
        mutating func adjust() {
            self = .Adjusted
        }
    
        mutating func restore() {
            self = .Simple
        }
    }
    
    var d: SimpleEnum = .Simple
    d.simpleDescription
    
    d.adjust()
    d.simpleDescription
    
    d.restore()
    d.simpleDescription
    

    Also notice that in the examples given by Apple for SimpleClass and SimpleStructure prior to this experiment, the simple description is lost internally - you cannot get the original value back (unless of course you save it outside of the class/structure); this is what prompted me to create a restore() method for the SimpleEnum example, which allows you to toggle it back and forth between values. Hope this is useful to someone!

    0 讨论(0)
  • 2020-12-22 17:15

    Another variation: Using associated values to hold and display previous option (of the form "Selected 1, adjusted from 2, adjusted from 1, adjusted from 2, adjusted from 1")

    protocol ExampleProtocol {
         var simpleDescription: String { get }
         mutating func adjust()
    }
    
    indirect enum EnumWithDescription: ExampleProtocol {
        case option1(EnumWithDescription?)
        case option2(EnumWithDescription?)
        var simpleDescription: String {
            return "Selected " + getDescription()
        }
        internal func getDescription() -> String {
            var currentValue: String
            let previousValue : EnumWithDescription?
            switch self {
            case .option1(let previous):
                currentValue = "1"
                previousValue = previous
            case .option2(let previous):
                currentValue = "2"
                previousValue = previous
            }
            if let adjustedFrom = previousValue?.getDescription() {
                return "\(currentValue) adjusted from \(adjustedFrom)"
            }
            else {
                return "\(currentValue)"
            }
        }
        mutating func adjust() {
            switch self {
            case .option1:
                self = .option2(self)
            case .option2:
                self = .option1(self)
            }
        }
    }
    var d = EnumWithDescription.option1(nil)
    d.simpleDescription
    d.adjust()
    d.adjust()
    d.simpleDescription
    // Output: "Selected 1, adjusted from 2, adjusted from 1, adjusted from 2, adjusted from 1"
    
    0 讨论(0)
提交回复
热议问题