简体   繁体   English

如何在Swift中检查Enum类型?

[英]How to check for Enum types in Swift?

I am writing a serializer that can serialize enums and other Swift types (strings, objects, etc.). 我正在编写一个序列化程序,可以序列化枚举和其他Swift类型(字符串,对象等)。 So I need to check if an Any parameter passed into my serializer is an Enum or something else. 所以我需要检查传递给我的序列化程序的Any参数是否是Enum或其他东西。 It seems like the only way to do this in Swift is using reflection. 似乎在Swift中执行此操作的唯一方法是使用反射。 Does the code below seem reasonable or is there a better way to check for Enum types? 下面的代码是否合理或是否有更好的方法来检查枚举类型?

enum Things {
    case Thing1
    case Thing2
}

let something:Any = Things.Thing1
let mirror = Mirror(reflecting: something)
if (mirror.displayStyle == .Enum) {
    print("Reflected type is Enum") // works
}
enum Things {
    case Thing1
    case Thing2
}

let something:Any = Things.Thing1

something.dynamicType == Things.self // true

update based on discussion .. 根据讨论更新..

protocol P {}
enum Things:P {
    case Thing1
    case Thing2
}
enum Things2:P{
    case Things21
}

let something:Any = Things.Thing1
something.dynamicType == Things.self // true
if let p = something as? P {
    print(true)
}

let somethingelse: Any = Things2.Things21
if let p = somethingelse as? P {
    print(true)
}

Since Mirror.displayStyle is an optional enumeration, preferably use conditional unwrapping and type checking in same statement. 由于Mirror.displayStyle是可选的枚举,因此最好在同一语句中使用条件展开和类型检查。

You could extend Mirror.displayStyle by an .equals method to make it readily accessible in case you want to do this enum check frequently. 您可以通过.equals方法扩展Mirror.displayStyle ,以便在您想要经常进行枚举检查时随时访问它。

extension Mirror.DisplayStyle {
    func equals(displayCase: Mirror.DisplayStyle) -> Bool {
        return self == displayCase
    }
}

enum Things {
    case Thing1
    case Thing2
}

let something:Any = Things.Thing1
let mirror = Mirror(reflecting: something)

/* short form: using nil coalescing and ternary conditional operator */
mirror.displayStyle?.equals(.Enum) ?? false ? print("Reflected type is an Enum") : ()

/* another option: or using if-let */
if let _ = mirror.displayStyle?.equals(.Enum) {
   print("Reflected type is an Enum")
}

Note that you needn't explicitly create and store a Mirror instance for this check, but can do it all in one expression, for some instance something of type Any : 请注意,您不需要显式地创建和存储Mirror实例此检查,但可以做到这一切在一个表达式,对于一些比如something类型的Any

Mirror(reflecting: something).displayStyle?.equals(.Enum) ?? false ? print("Reflected type is an Enum") : ()

Finally, if you're just interesting in doing some simple action base on the DisplayStyle case of different Any instances, you could create a function that switches over the different cases of this enum. 最后,如果您只是根据不同Any实例的DisplayStyle案例做一些简单的操作,那么您可以创建一个函数来切换此枚举的不同情况。 Below, the "simple action" just prints the case. 下面,“简单动作”只打印案例。

//... 

func foo(mirror: Mirror) {
    if let dispStyle = mirror.displayStyle {
        switch(dispStyle) {
        case .Class: print("Reflected type is a Class")
        case .Collection: print("Reflected type is a Collection")
        case .Dictionary: print("Reflected type is a Dictionary")
        case .Enum: print("Reflected type is an Enum")
        case .Optional:  print("Reflected type is an Optional")
        case .Set:  print("Reflected type is a Set")
        case .Struct:  print("Reflected type is a Struct")
        case .Tuple:  print("Reflected type is a Tuple")
        }
    }
}

let something: Any = Things.Thing1
foo(Mirror(reflecting: something))

See also Language Reference for Mirror.DisplayStyle . 另请参见Mirror.DisplayStyle的语言参考

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM