Swift类型推断和类型检查问题

时间:2016-01-27 20:32:45

标签: swift casting swift2 optional anyobject

我不是在寻找如何正确解决的答案,而是为什么会这样。

以下是代码:

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)

我理解在第一个if循环中,param已投放到Int,然后打印出1

但为什么在第二个if循环中,if value is Int为真,然后打印出1.2

3 个答案:

答案 0 :(得分:4)

请看https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/WorkingWithCocoaDataTypes.html,具体来说:

  

无法使用AnyObject类型表示Swift数值结构类型的实例,例如Int,UInt,Float,Double和Bool,因为AnyObject仅表示类类型的实例。但是,当启用桥接到Foundation时,可以将Swift数值赋值为AnyObject类型的常量和变量,作为NSNumber类的桥接实例。

我们可以在游乐场看到这个:

let value = 1.2
value.dynamicType                   //Double.Type
value is Int                        //false
let castValue = value as AnyObject
castValue.dynamicType               //__NSCFNumber.Type (a private framework class, part of the NSNumber class cluster)
//NSNumber is bridged to Int, UInt, Float, Double, and Bool so `is` tests for those types will return `true`
castValue is Int                    //true
castValue is Float                  //true
//NSNumber is not bridged to String so an `is` test will return `false`
castValue is String                 //false

答案 1 :(得分:3)

b案例中,let value = paramvalue桥接到NSNumber类型。对于NSNumbervalue is Int将始终为真。

对于非桥接值:

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

这个答案假定基金会已被导入。没有基金会,您的任务将失败。

答案 2 :(得分:1)

好吧,如果您执行以下操作,似乎就是这样:

func isInt(param: AnyObject?) {

    if let value = param {
        if value is Double {
            print("I'm a double")
        }
    if value is Int{
            print("I'm an int")
        }else {
            print("Not Int")
        }
    }
}

它将为所有三个打印“我是双倍”,并且对于所有三个都打印“我是一个int”。似乎当它转到if语句时,它将值桥接到NSNumber,对于任何NSNumber类型都是如此。

但是,假设您执行以下操作:

if let value = param {
        if value is String {
            print("I'm a String")
        } 
        if value is Int{
            print("I'm an int")
        }else {
            print("Not Int")
        }
    }
}

因为String不是NSNumber类型,所以它将跳过并转到if值为Int,它是NSNumber类型并返回值。