在Swift中,AnyObject
如何支持下标,即使对于不可订阅的类型也是如此?例如:
let numbers: AnyObject = [11, 22, 33]
numbers[0] // returns 11
let prices: AnyObject = ["Bread": 3.49, "Pencil": 0.5]
prices["Bread"] // returns 3.49
let number: AnyObject = 5
number[0] // return nil
let number: AnyObject = Int(5)
number[0] // return nil
然而,如果我的number
被声明为Int
,则表示语法错误:
let number: Int = 5
number[0] // won't compile
有趣的是,Any
没有下标支持。
答案 0 :(得分:12)
仅当您导入Foundation
时,此功能才有效,因为在这种情况下,Swift会对Objective-C
类型进行桥接 - 在这种情况下类似于NSArray
的对象。
import Foundation
let numbers: AnyObject = [11, 22, 33] as AnyObject
type(of: numbers) //_SwiftDeferredNSArray.Type
如果你不导入Foundation
,那么你甚至不允许进行赋值(因为Swift数组是结构而不是对象)。
let numbers: AnyObject = [11, 22, 33] // error: contextual type 'AnyObject' cannot be used with array literal
你可以转发Any
,但是:
let numbers: Any = [11, 22, 33]
type(of: numbers) // Array<Int>.Type
import Foundation
为什么会这样做?这在AnyObject
类型说明中记录:
/// When used as a concrete type, all known `@objc` methods and
/// properties are available, as implicitly-unwrapped-optional methods
/// and properties respectively, on each instance of `AnyObject`. For
/// example:
///
/// class C {
/// @objc func getCValue() -> Int { return 42 }
/// }
///
/// // If x has a method @objc getValue()->Int, call it and
/// // return the result. Otherwise, return nil.
这意味着您甚至可以调用数组上的方法,这些方法不一定存在于NSArray
上,但存在于Objective-C
世界中,例如:
numbers.lowercaseString // nil
并且Swift将优雅地返回nil
值而不是抛出令人讨厌的object does not recognises selector
异常,就像在Objective-C中会发生的那样。如果这是好事还是坏事,还有待辩论:)
<强>更新强> 上面似乎只适用于属性和类似属性的方法,如果你尝试使用Objective-C方法,那么你将遇到无法识别的选择器问题:
import Foundation
@objc class TestClass: NSObject {
@objc var someProperty: Int = 20
@objc func someMethod() {}
}
let numbers: AnyObject = [11, 22, 33] as AnyObject
numbers.lowercaseString // nil
numbers.someMethod // nil
numbers.someMethod() // unrecognized selector
numbers.stringByAppendingString("abc") // unrecognized selector
答案 1 :(得分:5)
在为AnyObject
类型的对象赋值时,它与类型的桥接有关:
let numbers: AnyObject = [11, 22, 33]
print(numbers.dynamicType) // _SwiftDeferredNSArray.Type
let prices: AnyObject = ["Bread": 3.49, "Pencil": 0.5]
print(prices.dynamicType) // _NativeDictionaryStorageOwner<String, Double>.Type
let number: AnyObject = 5
print(number.dynamicType) // __NSCFNumber.Type
let anotherNumber: Int = 5
print(anotherNumber.dynamicType) // Int.Type
在幕后,_SwiftDeferredNSArray.Type
,_NativeDictionaryStorageOwner<String, Double>.Type
和__NSCFNumber.Type
必须支持下标,Int.Type
则不支持。{/ p>
这是假设您已导入基金会。有关纯Swift类型的说明,请参阅Cristik's answer。