I’m trying to determine if a given type t
(Any.Type
) is an optional type, I’m using this test
t is Optional<Any>.Type
but it returns always false.
So is there any way to achieve this?
In Swift, you can also use nil-coalescing operator to check whether a optional contains a value or not. It is defined as (a ?? b) . It unwraps an optional a and returns it if it contains a value, or returns a default value b if a is nil.
An Optional is a type on its own, actually one of Swift 4's new super-powered enums. It has two possible values, None and Some(T), where T is an associated value of the correct data type available in Swift 4.
Optional binding is a mechanism built into Swift to safely unwrap optionals. Since an optional may or may not contain a value, optional binding always has to be conditional. To enable this, conditional statements in Swift support optional binding, which checks if a wrapped value actually exists.
An optional acts as a container for a value of a particular type. The container holds a value or it doesn't. Type safety is a cornerstone of the Swift language. As a result, variables and constants need to be initialized before they can be accessed.
Therefore, Optional types are intended solely for method return types. Since fields constitute the internal state of a class and should not be visible to outside clients, if a field is considered optional, a getter can be created that returns an Optional object instead:
A variable whose type is Optional should never itself be null; it should always point to an Optional instance. If a null value is returned in place of an Optional object, this is a breach of the method contract on the part of the method developer.
In my opinion, having an optional-typed parameter in a function shows a design-flaw in every case. You either way have some decision to make if you do something with the parameter if it is there, or you do something else if it is not-and this flow is hidden inside the function.
Optional is primarily intended for use as a method return type where there is a clear need to represent "no result," and where using null is likely to cause errors. In general, an Optional should be used as a return value if: Optional return values are often used for queries that may or may not find a desired object.
Assuming that what you are trying to do is something like this:
let anyType: Any.Type = Optional<String>.self
anyType is Optional<Any>.Type // false
Sadly swift currently (as of Swift 2) does not support covariance nor contravariance and type checks directly against Optional.Type
cannot be done:
// Argument for generic parameter 'Wrapped' could not be inferred
anyType is Optional.Type // Causes error
An alternative is to make Optional
extend an specific protocol, and check for that type:
protocol OptionalProtocol {}
extension Optional : OptionalProtocol {}
let anyType: Any.Type = Optional<String>.self
anyType is OptionalProtocol.Type // true
A bit late for the party. But, I ran into the same problem. Here is my code.
func isOptional(_ instance: Any) -> Bool {
let mirror = Mirror(reflecting: instance)
let style = mirror.displayStyle
return style == .optional
}
let a: Int = 1 // false
let b: Int? = 2 // true
let c: Double = 3.0 // false
let d: Double? = 4.0 // true
let e: NSString = "Hello" // false
let f: NSString? = "Hello" // true
isOptional(a) // fasle
isOptional(b) // true - warning
isOptional(c) // false
isOptional(d) // true - warning
isOptional(e) // false
isOptional(f) // true - warning
It looks good to me. swift4
You can do something like this:
extension Mirror {
static func isOptional(any: Any) -> Bool {
guard let style = Mirror(reflecting: any).displayStyle,
style == .optional else { return false }
return true
}
}
Usage:
XCTAssertTrue(Mirror.isOptional(any: Optional(1)))
Or if you need to cast from Any to Optional
protocol _Optional {
var isNil: Bool { get }
}
extension Optional: _Optional {
var isNil: Bool { return self == nil }
}
func isNil (_ input: Any) -> Bool {
return (input as? _Optional)?.isNil ?? false
}
Usage:
isNil(nil as String?) // true
isNil("") // false
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