Accessing an Enumeration association value in Swift

后端 未结 7 704
情深已故
情深已故 2020-11-27 14:46

In this code I\'ve written a really useless enum that defines a possible Number with Int or Float.

I can\'t understand how can I access the value that

相关标签:
7条回答
  • 2020-11-27 14:50

    For sake of completeness, enum's association value could be accesed also using if statement with pattern matching. Here is solution for original code:

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

    This solution is described in detail in: https://appventure.me/2015/10/17/advanced-practical-enum-examples/

    0 讨论(0)
  • 2020-11-27 14:50

    Swift 4,

    I have created a simple enum with associated values for handling firebase database reference paths

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

    Use it like as shown

    //Pass Database refenence root as parameter with your request id
    let dbPath = FirebaseDBConstants.UserRequest(database: database, requestID: requestId).getDBPath()
    
    0 讨论(0)
  • 2020-11-27 14:51

    The value is associated to an instance of the enumeration. Therefore, to access it without a switch, you need to make a getter and make it available explicitly. Something like below:

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

    Maybe in the future something like that may be automatically created or a shorter convenience could be added to the language.

    0 讨论(0)
  • 2020-11-27 14:55

    If you're using guard, you can write like below:

    enum Action {
        case .moveTab(index: Int)
    }
    
    guard let case .moveTab(index) = someAction else { return }
    
    0 讨论(0)
  • 2020-11-27 15:01

    like @iQ. answer, you can use property in enum also

    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)")
    
    0 讨论(0)
  • 2020-11-27 15:06

    It surprises me that Swift 2 (as of beta 2) does not address this. Here's an example of a workaround approach for now:

    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)
    

    If your enum mixes cases with and without associated values, you'll need to make the return type an optional. You could also return literals for some cases (that do not have associated values), mimicking raw-value typed enums. And you could even return the enum value itself for non-associated, non-raw-type cases. For example:

    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"
    
    0 讨论(0)
提交回复
热议问题