type the switch raw not have enum does cannot swift enums swift-protocols

the - switch self swift



¿Cómo hacer que una enumeración se ajuste a un protocolo en Swift? (15)

Aquí está mi opinión al respecto.

Como esta es una enum y no una class , debes pensar diferente (TM) : es tu descripción la que tiene que cambiar cuando cambia el "estado" de tu enum (como lo señala @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

Espero que ayude.

La documentación de Swift dice que las clases , las estructuras y las enumeraciones pueden ajustarse a los protocolos, y puedo llegar al punto en que todos se ajustan. Pero no puedo hacer que la enumeración se comporte como los ejemplos de clase y estructura :

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

No he descubierto cómo hacer que la simpleDescription cambie como resultado de llamar a adjust() . Mi ejemplo obviamente no hará eso porque el getter tiene un valor codificado, pero ¿cómo puedo establecer un valor para la simpleDescription mientras sigo cumpliendo con el ExampleProtocol ?


Aquí hay otro enfoque, usando solo el conocimiento obtenido de la gira hasta ese punto *

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

Si desea que adjust() actúe como un alternar (aunque no hay nada que sugiera que este sea el caso), use:

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

* (Aunque no menciona explícitamente cómo especificar un tipo de devolución y un protocolo)


Aquí hay una solución que no cambia el valor enum actual, sino sus valores de instancia (en caso de que sea útil para cualquier persona).

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


Aquí se basa en la respuesta de Jack:

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


Es un link sobre enum en swift.

Las estructuras y las enumeraciones son tipos de valores. Por defecto, las propiedades de un tipo de valor no se pueden modificar desde sus métodos de instancia. link

Entonces, debes usar la función de mutación.

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


Estaba pensando que el objetivo es simplemente conservar el estado y usar una descripción para hacer que el estado actual sea más fácil de leer:

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


Este es mi intento:

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


Este experimento me sorprendió también, debido a los ejemplos previos SimpleClass y SimpleStructure que mostraban la propiedad de la descripción simple siendo modificada internamente, lo que me hizo pensar que tenía que hacer lo mismo. Después de revisar las otras respuestas publicadas aquí y leer la documentación oficial de Apple Swift 2.1, se me ocurrió esto:

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

También observe que en los ejemplos dados por Apple para SimpleClass y SimpleStructure antes de este experimento, la descripción simple se pierde internamente: no puede recuperar el valor original (a menos que, por supuesto, lo guarde fuera de la clase / estructura); esto es lo que me impulsó a crear un método de restauración () para el ejemplo de SimpleEnum, que le permite alternar entre los valores. ¡Espero que sea útil para alguien!


Mi primera contribución aquí:

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

Gracias por los demás!


No es posible definir variables sin getter y setter en enumeraciones y, por lo tanto, es imposible tener una variable que pueda modificar.

Puedes conformarte al protocolo pero no puedes tener el mismo comportamiento con la mutación que en las clases.


Otra opción es ajustar () para cambiar entre mayúsculas y minúsculas de la siguiente manera:

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


Qué tal esto

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"


Se me ocurrió esto

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


aquí está mi código

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


Otra variación: Usar valores asociados para mantener y mostrar la opción anterior (de la forma "Seleccionado 1, ajustado desde 2, ajustado desde 1, ajustado desde 2, ajustado desde 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"