Determine if Any.Type is Optional

前端 未结 4 1663
滥情空心
滥情空心 2020-12-05 19:55

I’m trying to determine if a given type t (Any.Type) is an optional type, I’m using this test

t is Optional.Type
         


        
相关标签:
4条回答
  • 2020-12-05 19:56

    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

    0 讨论(0)
  • 2020-12-05 20:02

    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
    
    0 讨论(0)
  • 2020-12-05 20:03

    You could use generics to achieve this:

    func isOptional<T>(x:T?)->Bool
    {
        return true
    }
    
    func isOptional<T>(x:T)->Bool
    {
        return false
    }
    

    Edit

    The code above can be used to know if a variable is of optional type. The only way i've figured out to know about a variable containing a type is by using reflection:

    var t1:Any.Type=(String?).self
    var t2:Any.Type=(String).self
    Mirror(reflecting: t1).description
    Mirror(reflecting: t2).description
    

    The first call to Mirror gives the string "Mirror for Optional<String>.Type", and the second gives "Mirror for String.Type".

    I understand that comparing string is not a convenient way to do this check, i will try again to find something more performant..

    0 讨论(0)
  • 2020-12-05 20:12

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