I am writing a serializer that can serialize enums and other Swift types (strings, objects, etc.). So I need to check if an Any parameter passed into my serializer is an Enum or something else. It seems like the only way to do this in Swift is using reflection. 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
}
Since Mirror.displayStyle
is an optional enumeration, preferably use conditional unwrapping and type checking in same statement.
You could extend Mirror.displayStyle
by an .equals
method to make it readily accessible in case you want to do this enum check frequently.
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(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. 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.
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)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With