Search code examples
swiftcastingswift2option-typeanyobject

Swift type inference and type checking issue


I'm not looking for an answer like how to do it correctly but why this happens.

Here is the code:

func isInt(param: AnyObject?) {
    if let value = param as? Int {
        print(value)
    } else {
        print("Not Int")
    }

    if let value = param {
        if value is Int {
            print(value)
        } else {
            print("Not Int")
        }
    }
}

let a:AnyObject? = 1.2
let b:Float? = 1.2
let c:Double? = 1.2

isInt(a)
isInt(b)
isInt(c)

I understand in the first if loop, the param is casted to Int and then print out 1.

But why in second if loop, if value is Int is true and then print out 1.2?


Solution

  • In your b case, let value = param bridges value to an NSNumber type. For NSNumber, value is Int will always be true.

    For unbridged values:

    a is Int // always true, AnyObject bridges to NSNumber here
    b is Int // false, cast from Float to Int always fails
    c is Int // false, cast from Double to Int always fails
    

    This answer assumes Foundation has been imported. Without Foundation, your assignments will fail.