在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
Run Code Online (Sandbox Code Playgroud)
然而,如果我number被声明为Int那么这是一个语法错误:
let number: Int = 5
number[0] // won't compile
Run Code Online (Sandbox Code Playgroud)
有趣的是,Any没有下标支持.
Cri*_*tik 12
这只适用于导入Foundation,因为Swift在这种情况下正在做一些桥接Objective-C类型 - NSArray在这种情况下是类似对象.
import Foundation
let numbers: AnyObject = [11, 22, 33] as AnyObject
type(of: numbers) //_SwiftDeferredNSArray.Type
Run Code Online (Sandbox Code Playgroud)
如果不导入Foundation,则甚至不允许进行赋值(因为Swift数组是结构而不是对象).
let numbers: AnyObject = [11, 22, 33] // error: contextual type 'AnyObject' cannot be used with array literal
Run Code Online (Sandbox Code Playgroud)
你可以投Any,但:
let numbers: Any = [11, 22, 33]
type(of: numbers) // Array<Int>.Type
Run Code Online (Sandbox Code Playgroud)
为什么这样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.
Run Code Online (Sandbox Code Playgroud)
这意味着你甚至可以在数组上调用不一定存在NSArray但在Objective-C世界中存在的方法,例如:
numbers.lowercaseString // nil
Run Code Online (Sandbox Code Playgroud)
并且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
Run Code Online (Sandbox Code Playgroud)
在为类型对象赋值时,它与类型的桥接有关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
Run Code Online (Sandbox Code Playgroud)
在幕后,_SwiftDeferredNSArray.Type,_NativeDictionaryStorageOwner<String, Double>.Type,并且__NSCFNumber.Type必须同时支持标Int.Type没有.
这假设您已导入Foundation.有关纯Swift类型的解释,请参阅Cristik的答案.
| 归档时间: |
|
| 查看次数: |
695 次 |
| 最近记录: |