首页 文章

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

提问于
浏览
80

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

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

15 回答

  • 1

    这是我的尝试:

    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
    
  • 138

    这是我的看法 .

    由于这是一个 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
    

    希望有所帮助 .

  • 1

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

    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
    

    如果你想 adjust() 作为一个切换(虽然没有任何暗示是这种情况),使用:

    mutating func adjust() {
        switch self {
        case .Basic:
            self = .Adjusted
        default:
            self = .Basic
        }
    }
    

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

  • 41

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

    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
    
  • 7

    在枚举中没有getter和setter定义变量是不可能的,因此不可能有一个可以修改的变量 .

    您可以符合协议,但不能像在类中一样进行变异 .

  • 0

    关于swift中的enum是一个link .

    结构和枚举是值类型 . 默认情况下,无法在其实例方法中修改值类型的属性 . link

    然后,你必须使用变异功能 .

    enum ProtocolEnum: ExampleProtocol {
        case on, off
        var simpleDescription: String {
            switch self {
            case .on:
                return "Switch is ON"
            case .off:
                return "Switch is OFF"
            }
        }
        mutating func adjust() {
            switch self {
            case .on:
                self = off
            case .off:
                self = on
            }
        }
    }
    
    var c = ProtocolEnum.on
    c.simpleDescription
    c.adjust()
    let cDescription = c.simpleDescription
    
  • 1

    另一种选择是adjust()在案例之间翻转,如下所示:

    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
        }
    }
    
  • 11

    以杰克的答案为基础:

    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

    我想出了这个

    protocol ExampleProtocol {
        var simpleDescription: String { get }
        mutating func adjust()
    }
    
    enum Seat: ExampleProtocol {
        case WindowSeat, MiddleSeat, AisleSeat
    
        var simpleDescription : String {
            switch self {
            case .WindowSeat:
                return "Window Seat"
            case .MiddleSeat:
                return "Middle Seat"
            case .AisleSeat:
                return "Aisle Seat"
            }
        }
    
        mutating func adjust() {
            switch self {
            case .WindowSeat:
                self = .MiddleSeat
            case .MiddleSeat:
                self = . AisleSeat
            case .AisleSeat:
                self = .WindowSeat
            }
        }
    }
    
    var seat = Seat.MiddleSeat
    print(seat.simpleDescription) // Middle Seat
    seat.adjust()
    print(seat.simpleDescription) // Aisle Seat
    
  • 0

    这是我的代码

    enum SimpleEnum: ExampleProtocol {
        case Base, Adjusted
        var simpleDescription: String {
            get {
                var description = "A simple enum."
                switch self {
                case .Base:
                    return description
                case .Adjusted:
                    return description + " - [adjusted]"
                }
            }
        }
        mutating func adjust() {
            self = SimpleEnum.Adjusted
        }
    }
    var simpleEnum = SimpleEnum.Base
    simpleEnum.adjust()
    simpleEnum.simpleDescription
    
  • 2

    我的第一个贡献是:

    enum SimpleEnum: ExampleProtocol {
        case Basic(String), Adjusted(String)
        init() {
            self = SimpleEnum.Basic("A simple Enum")
    
        }
    
        var simpleDescription: String {
            get {
                switch self {
                case let .Basic(string):
                    return string
                case let .Adjusted(string):
                    return string
                }
            }
        }
    
        mutating func adjust() {
            self = SimpleEnum.Adjusted("full adjusted")
    
        }
    }
    
    var c = SimpleEnum()
    c.adjust()
    let cDescription = c.simpleDescription
    

    谢谢别人!

  • 0

    由于之前的SimpleClass和SimpleStructure示例显示内部修改了simpleDescription属性,这个实验也让我失望了,这让我觉得我需要做同样的事情 . 在查看了此处发布的其他答案并阅读官方Apple Swift 2.1文档后,我想出了这个:

    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
    

    另请注意,在本实验之前,Apple为SimpleClass和SimpleStructure给出的示例中,简单描述在内部丢失 - 您无法获得原始值(除非您将其保存在类/结构之外);这就是促使我为SimpleEnum示例创建一个restore()方法的原因,它允许您在值之间来回切换它 . 希望这对某人有用!

  • 0

    我认为目标只是保留状态并使用描述来使当前状态更容易阅读:

    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
    
  • -1

    Another variation: Using associated values to hold and display previous option (格式为"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"
    
  • 4

    这个怎么样

    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"
    

相关问题