为什么这种类型问题的Swift代码不会产生错误?

时间:2021-12-29 17:05:59

Consider the following code:

考虑下面的代码:

func f(dict: [String: AnyObject]) {
    let x = dict["mykey"]?.integerValue
    // Do something with x
}

There is no indication of what type dict["mike"] could be, yet I can invoke integerValue on it. How does this code not cause an error, or at least a warning?

没有迹象表明dict类型(“mike”)可以是什么类型,但是我可以在它上调用integerValue。这段代码如何不会导致错误,或者至少是警告?

3 个解决方案

#1


2  

This does not cause an error or warning because AnyObject allows any NSObject method to be called on it the equivalent of id in Objective-C. So in this case the compiler does not know what it will be there and if the object does not support integerValue then you will get 0 back at the end of it based on testing in the playground.

这不会导致错误或警告,因为AnyObject允许在Objective-C中调用与id相同的NSObject方法。在这种情况下,编译器不知道它会在哪里如果对象不支持integerValue那么你会在最后得到0基于在操场上的测试。

#2


0  

The return from .integerValue is an optional Int: let x: Int?. The property integerValue will initialize an integer using the value for key "myKey"; if it fails, however, if will return nil.

从。integervalue返回的是一个可选的Int:让x: Int?属性integerValue将使用key“myKey”的值初始化一个整数;如果失败,if将返回nil。

If the AnyObject value for a certain key in your dictionary contain no successful method to initialize an integer given the value (i.e., by integerValue computed property), then the last step after the optional chaining on x in your question above will return nil, e.g.:

如果dictionary中的某个键的AnyObject值包含没有成功的方法来初始化给定值的整数(例如:,使用integerValue computed property),然后在上面问题中对x进行可选链接后的最后一步将返回nil,例如:

class MyClass {
    var myInt : Int
    init() {
        myInt = 1
    }
}

var myDict : [String:AnyObject] = ["myKey":MyClass()]
let a = myDict["myKey"]               // MyClass, OK
let x = myDict["myKey"]!.integerValue // nil

Hence, note that it's not the actual lookup for key "myKey" that returns nil above, but the attempted call to property .integerValue on an AnyObject instance of a MyClass() object, from which it, naturally, doesn't exist any (for the compiler) know way to construct an Int from.

因此,请注意,上面返回nil的并不是键“myKey”的实际查找,而是对MyClass()对象的AnyObject实例的. integervalue的尝试调用,在这个对象中,它自然不存在(对于编译器来说)知道如何构造Int的方法。

#3


0  

The ? Optional-unwrapping is a red herring. It would be better to write the example like this:

的吗?选择解除包装是在转移注意力。最好写这样的例子:

func f(dict: [String: AnyObject]) {
    let x = dict["mykey"]!.integerValue
}

Or even better, like this:

或者更好,像这样:

let ao : AnyObject = "howdy"
ao.integerValue

As long is something is typed as an AnyObject, any known class message can be sent to it. Swift will deal safely with the result. Thus, for example:

只要某个对象是按AnyObject类型输入的,任何已知的类消息都可以发送给它。Swift将安全地处理结果。因此,例如:

class Dog{}
let d:AnyObject = Dog()
d.integerValue // nil, because a Dog has no integerValue property

#1


2  

This does not cause an error or warning because AnyObject allows any NSObject method to be called on it the equivalent of id in Objective-C. So in this case the compiler does not know what it will be there and if the object does not support integerValue then you will get 0 back at the end of it based on testing in the playground.

这不会导致错误或警告,因为AnyObject允许在Objective-C中调用与id相同的NSObject方法。在这种情况下,编译器不知道它会在哪里如果对象不支持integerValue那么你会在最后得到0基于在操场上的测试。

#2


0  

The return from .integerValue is an optional Int: let x: Int?. The property integerValue will initialize an integer using the value for key "myKey"; if it fails, however, if will return nil.

从。integervalue返回的是一个可选的Int:让x: Int?属性integerValue将使用key“myKey”的值初始化一个整数;如果失败,if将返回nil。

If the AnyObject value for a certain key in your dictionary contain no successful method to initialize an integer given the value (i.e., by integerValue computed property), then the last step after the optional chaining on x in your question above will return nil, e.g.:

如果dictionary中的某个键的AnyObject值包含没有成功的方法来初始化给定值的整数(例如:,使用integerValue computed property),然后在上面问题中对x进行可选链接后的最后一步将返回nil,例如:

class MyClass {
    var myInt : Int
    init() {
        myInt = 1
    }
}

var myDict : [String:AnyObject] = ["myKey":MyClass()]
let a = myDict["myKey"]               // MyClass, OK
let x = myDict["myKey"]!.integerValue // nil

Hence, note that it's not the actual lookup for key "myKey" that returns nil above, but the attempted call to property .integerValue on an AnyObject instance of a MyClass() object, from which it, naturally, doesn't exist any (for the compiler) know way to construct an Int from.

因此,请注意,上面返回nil的并不是键“myKey”的实际查找,而是对MyClass()对象的AnyObject实例的. integervalue的尝试调用,在这个对象中,它自然不存在(对于编译器来说)知道如何构造Int的方法。

#3


0  

The ? Optional-unwrapping is a red herring. It would be better to write the example like this:

的吗?选择解除包装是在转移注意力。最好写这样的例子:

func f(dict: [String: AnyObject]) {
    let x = dict["mykey"]!.integerValue
}

Or even better, like this:

或者更好,像这样:

let ao : AnyObject = "howdy"
ao.integerValue

As long is something is typed as an AnyObject, any known class message can be sent to it. Swift will deal safely with the result. Thus, for example:

只要某个对象是按AnyObject类型输入的,任何已知的类消息都可以发送给它。Swift将安全地处理结果。因此,例如:

class Dog{}
let d:AnyObject = Dog()
d.integerValue // nil, because a Dog has no integerValue property