如何使一个枚举符合Swift协议?

Swift文档说, 结构枚举都可以符合协议,我可以达到一致的地步。 但是我不能让这个枚举类似于结构的例子:

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 

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

这是我的尝试:

 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 

这是我的看法。

因为这是一个enum而不是一个class ,所以你必须认为不同(TM) :当你的enum的“状态”发生变化时,你的描述必须改变(正如@胡强所指出的那样)。

 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 

希望有所帮助。

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

 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()作为一个切换(虽然没有什么build议这种情况),使用:

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

*(虽然没有明确提及如何指定返回types协议)

这是一个解决scheme,不改变当前的枚举值,但他们的实例值(以防万一它是有用的)。

 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 

在enums中没有getter和setter的情况下定义variables是不可能的,因此不可能有可以修改的variables。

你可以遵守这个协议,但是你不能像在类中那样具有相同的行为。

这是一个关于快速枚举的链接 。

结构和枚举是值types。 默认情况下,值types的属性不能从其实例方法中修改。 链接

然后,你必须使用变异函数。

 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 

另一个选项是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 } } 

杰克的回答如下:

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

我想出了这个

 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 

这是我的代码

 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 

我的第一个贡献是:

 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 

感谢别人!

由于之前的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示例创buildrestore()方法的原因,它允许您在值之间来回切换。 希望这对别人有用!

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

 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 

另一种变化:使用相关的值来保存和显示以前的选项 (forms为“select1,从2调整,从1调整,从2调整,从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" 

这个怎么样

 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"