在Swift中访问枚举关联值

时间:2014-06-17 12:14:58

标签: swift

在这段代码中,我编写了一个非常无用的枚举,用Int或Float定义了一个可能的Number

我无法理解如何访问我使用关联设置的值。如果我尝试打印它,我会得到(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)")

7 个答案:

答案 0 :(得分:65)

为了完整起见,也可以使用带有模式匹配的if语句来加入enum的关联值。这是原始代码的解决方案:

li

此解决方案详见:https://appventure.me/2015/10/17/advanced-practical-enum-examples/

答案 1 :(得分:59)

该值与枚举的实例相关联。因此,要在没有开关的情况下访问它,您需要制作一个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())

将来可能会自动创建类似的内容,或者可以为语言添加更短的便利性。

答案 2 :(得分:11)

令我惊讶的是,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 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"

答案 3 :(得分:6)

像@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 :(得分:3)

我使用过这样的东西:

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

答案 5 :(得分:0)

如果你正在使用后卫,你可以写如下:

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

guard let case .moveTab(index) = someAction else { return }

答案 6 :(得分:0)

快捷键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()