Acceder a un valor de asociación de enumeración en Swift

En este código he escrito una enumeración realmente inútil que define un Number posible con Int o Float.

No puedo entender cómo puedo acceder al valor que establecí con la asociación. Si bash imprimirlo, obtengo solo (Enum Value)

 enum Number { case int (Int) case float (Float) } let integer = Number.int(10) let float = Number.float(10.5) println("integer is \(integer)") println("float is \(float)") 

El valor está asociado a una instancia de la enumeración. Por lo tanto, para acceder a él sin un interruptor, necesita hacer un getter y hacerlo disponible explícitamente. Algo como a continuación:

 enum Number { case int(Int) case float(Float) func get() -> NSNumber { switch self { case .int(let num): return num case .float(let num): return num } } } var vInteger = Number.int(10) var vFloat = Number.float(10.5) println(vInteger.get()) println(vFloat.get()) 

Quizás en el futuro, algo así se cree automáticamente o se pueda agregar una conveniencia más corta al idioma.

En aras de la integridad, el valor de asociación de enum podría ser accesado también usando la instrucción if con coincidencia de patrones. Aquí hay una solución para el código original:

 enum Number { case int (Int) case float (Float) } let integer = Number.int(10) let float = Number.float(10.5) if case let .int(i) = integer { print("integer is \(i)") } if case let .float(f) = float { print("float is \(f)") } 

Esta solución se describe en detalle en: https://appventure.me/2015/10/17/advanced-practical-enum-examples/

Me sorprende que Swift 2 (a partir de beta 2) no solucione esto. Aquí hay un ejemplo de un enfoque alternativo por ahora:

 enum TestAssociatedValue { case One(Int) case Two(String) case Three(AnyObject) func associatedValue() -> Any { switch self { case .One(let value): return value case .Two(let value): return value case .Three(let value): return value } } } let one = TestAssociatedValue.One(1) let oneValue = one.associatedValue() // 1 let two = TestAssociatedValue.Two("two") let twoValue = two.associatedValue() // two class ThreeClass { let someValue = "Hello world!" } let three = TestMixed.Three(ThreeClass()) let threeValue = three. associatedValue() as! ThreeClass print(threeValue.someValue) 

Si su enumeración mezcla casos con y sin valores asociados, deberá hacer que el tipo de devolución sea opcional. También puede devolver literales para algunos casos (que no tienen valores asociados), imitando enumeraciones de tipo de valor sin formato. E incluso podría devolver el valor enum en sí mismo para casos no asociados y no en bruto. Por ejemplo:

 enum TestMixed { case One(Int) case Two(String) case Three(AnyObject) case Four case Five func value() -> Any? { switch self { case .One(let value): return value case .Two(let value): return value case .Three(let value): return value case .Four: return 4 case .Five: return TestMixed.Five } } } let one = TestMixed.One(1) let oneValue = one.value() // 1 let two = TestMixed.Two("two") let twoValue = two.value() // two class ThreeClass { let someValue = "Hello world!" } let three = TestMixed.Three(ThreeClass()) let threeValue = three.value() as! ThreeClass print(threeValue.someValue) let four = TestMixed.Four let fourValue = four.value() // 4 let five = TestMixed.Five let fiveValue = five.value() as! TestMixed switch fiveValue { case TestMixed.Five: print("It is") default: print("It's not") } // Prints "It is" 

como @iQ. respuesta, puedes usar la propiedad en enum también

 enum Number { case int (Int) var value: Int { switch self { case .int(let value): return value } } } let integer = Number.int(10) println("integer is \(integer.value)") 

He usado algo como esto:

 switch number { case .int(let n): println("integer is \(n)") case .float(let n): println("float is \(n)") } 

Si está usando guardia, puede escribir de la siguiente manera:

 enum Action { case .moveTab(index: Int) } guard let case .moveTab(index) = someAction else { return } 

Swift 4,

Creé una enumeración simple con los valores asociados para manejar las rutas de referencia de la base de datos de firebase

 import Firebase enum FirebaseDBConstants { case UserLocation(database : DatabaseReference, userID :String) case UserRequest(database : DatabaseReference, requestID :String) func getDBPath() -> DatabaseReference { switch self { case .UserLocation(let database,let userID): return database.root.child(FirebaseDBEnvironmentEnum.getCurrentEnvioronMent()).child("Location").child(userID).child("JSON") case .UserRequest(let database,let requestID): return database.root.child(FirebaseDBEnvironmentEnum.getCurrentEnvioronMent()).child("Request").child(requestID) default: break } } } 

Úselo como se muestra

 //Pass Database refenence root as parameter with your request id let dbPath = FirebaseDBConstants.UserRequest(database: database, requestID: requestId).getDBPath()