15

在 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

然而,如果 mynumber被声明为Intthen 它是一个语法错误:

let number: Int = 5
number[0]        // won't compile

有趣的是,Any没有下标支持。

4

2 回答 2

12

这仅在您 import 时才有效Foundation,因为 Swift 在这种情况下正在做一些Objective-C类型的桥接 - 在这种情况下是一个NSArray-like 对象。

import Foundation

let numbers: AnyObject = [11, 22, 33] as AnyObject
type(of: numbers) //_SwiftDeferredNSArray.Type

如果你不 import 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
于 2016-01-21T22:38:12.000 回答
5

在将值分配给 type 的对象时,它与类型的桥接有关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但不支持。

这是假设你已经导入了 Foundation。有关纯 Swift 类型的解释,请参阅Cristik 的回答

于 2016-01-21T22:34:59.423 回答