Доступ к значению ассоциации Enumeration в Swift

В этом коде я написал очень бесполезное перечисление, которое определяет возможное Number с Int или Float.

Я не могу понять, как получить доступ к значению, которое я установил с помощью ассоциации. Если я попытаюсь распечатать его, я получу только (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)") 

Значение связано с экземпляром enums. Поэтому, чтобы получить доступ к нему без коммутатора, вам нужно сделать getter и сделать его доступным явно. Что-то вроде ниже:

 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()) 

Возможно, в будущем что-то подобное может быть автоматически создано или более короткое удобство может быть добавлено к языку.

Для полноты, значение ассоциации enum можно было бы также использовать, используя оператор if с сопоставлением с образцом. Вот решение для исходного кода:

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

Это решение подробно описано в: https://appventure.me/2015/10/17/advanced-practical-enum-examples/

Меня удивляет, что Swift 2 (с бета-версии 2) не затрагивает этого. Ниже приведен пример обходного подхода:

 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) 

Если ваше перечисление смешивает случаи со связанными значениями и без них, вам необходимо сделать тип возвращаемого значения необязательным. Вы также можете возвращать литералы для некоторых случаев (которые не имеют связанных значений), имитируя типизированные enums с необработанным значением. И вы даже можете вернуть значение enum для несвязанных, не-сырых типов. Например:

 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" 

как @iQ. ответ, вы можете использовать свойство в перечислении также

 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)") 

Я использовал что-то вроде этого:

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

Если вы используете охрану, вы можете написать, как показано ниже:

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

Swift 4,

Я создал простое перечисление со связанными значениями для обработки ссылок базы данных базы данных 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 } } } 

Используйте его, как показано на рисунке

 //Pass Database refenence root as parameter with your request id let dbPath = FirebaseDBConstants.UserRequest(database: database, requestID: requestId).getDBPath() 
  • Как установить интервал между ячейками и UICollectionView - отношение UICollectionViewFlowLayout?
  • Как управлять расстоянием между строками в UILabel
  • Swift Alamofire: как получить код статуса ответа HTTP
  • Swift - Разрешение математической операции в строке
  • Первые имена параметров Swift 3
  • Поймать NSException в Swift
  • NSFileManager fileExistsAtPath: isDirectory и быстрый
  • Пользовательский навигатор ios 11 переходит в строку состояния
  • В чем разница между функциями и закрытием?
  • dyld: библиотека не загружена: @ rpath / libswift_stdlib_core.dylib
  • Сгладить массив массивов в Swift
  • Давайте будем гением компьютера.