Struct Decodable с Int или строковым значением - Swift [дубликат]

Это легко.

Пример из MSDN:

  public static void Main () {// Использовать имя файла для загрузки сборки в текущее // приложение  домен.  Сборка a = Assembly.Load («пример»);  // Получить тип для использования.  Введите myType = a.GetType («Пример»);  // Получить метод для вызова.  MethodInfo myMethod = myType.GetMethod ("MethodA");  // Создаем экземпляр.  object obj = Activator.CreateInstance (myType);  // Выполнить метод.  myMethod.Invoke (obj, null);  }  

Вот ссылка:

https://msdn.microsoft.com/en-us/library/25y1ya39.aspx [ ! d5]

30
задан MatterGoal 17 June 2014 в 13:14
поделиться

7 ответов

Значение связано с экземпляром перечисления. Поэтому, чтобы получить доступ к нему без коммутатора, вам нужно сделать 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())

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

44
ответ дан Binarian 16 August 2018 в 10:17
поделиться

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

enum Action {
    case .moveTab(index: Int)
}

guard let case .moveTab(index) = someAction else { return }
1
ответ дан BurtK 16 August 2018 в 10:17
поделиться

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

switch number {
case .int(let n):
    println("integer is \(n)")
case .float(let n):
    println("float is \(n)")
}
3
ответ дан manojlds 16 August 2018 в 10:17
поделиться
  • 1
    Я хотел бы получить доступ к значению напрямую, а не через коммутатор. – MatterGoal 17 June 2014 в 13:24
  • 2
    @MatterGoal - Как вы можете получить к нему доступ, не зная, что это такое? Насколько я знаю, коммутатор - единственный способ. – manojlds 17 June 2014 в 13:39
  • 3
    @MatterGoal - как указывали маноджиды, любая попытка доступа к связанным значениям должна быть связана с проверкой для случая enum, поэтому коммутатор действительно не добавляет никакого кода, возможно, перемещение его по всему - это все. – David Berry 17 June 2014 в 16:59
  • 4
    – Nicolas Miari 2 March 2016 в 05:14
  • 5
    @NicolasMiari - я добавил решение с извлечением инструкции if: stackoverflow.com/a/37159851/466677 – Marek Gregor 11 May 2016 в 10:28

Для полноты, значение ассоциации 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/

50
ответ дан Marek Gregor 16 August 2018 в 10:17
поделиться

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()
0
ответ дан Pramod More 16 August 2018 в 10:17
поделиться

Меня удивляет, что 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)

Если ваше перечисление смешивает случаи со связанными значениями и без них, вам нужно сделать тип возвращаемого значения необязательным. Вы также можете возвращать литералы для некоторых случаев (которые не имеют связанных значений), имитируя типизированные перечисления с необработанным значением. И вы даже можете вернуть значение 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"
8
ответ дан Scott Gardner 16 August 2018 в 10:17
поделиться

, как @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)")
4
ответ дан Zoon Nooz 16 August 2018 в 10:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: