2016-01-21 9 views
15

Swiftでは、subscriptableでないタイプの場合でも、AnyObjectは添え字をどのようにサポートしていますか?例: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

関連:http://stackoverflow.com/questions/24154304/why-is-an-array-an-anyobject-in-swift – dfri

+0

質問を理解することは非常に興味深いです場面の背後にあるものだが、かなり理論的である。実際には、コンパイラが適切な型を推論でき、開発者が正確に知っているオブジェクトに対して型アノテーション 'AnyObject'を使用しません。Appleは、とにかく(そのような種類の)タイプの注釈を使用することを強く奨励します。 – vadian

+1

NSJSONSerialization.JSONObjectWithData'は 'AnyObject'を返します –

答えて

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を、そしてInt.Typeはそうではない__NSCFNumber.Typeは添字をサポートしている必要があります。

これは、Foundationをインポートしたことを前提としています。純粋なスウィフトタイプの説明については、Cristik's answerを参照してください。

12

Foundationをインポートした場合、Swiftがこの場合、Objective-Cタイプにブリッジするブリッジ - この場合はNSArrayのようなオブジェクトです。

import Foundation 

let numbers: AnyObject = [11, 22, 33] 
numbers.dynamicType //_SwiftDeferredNSArray.Type 

あなたがFoundationをインポートしない場合(スウィフト配列は構造体ではなくオブジェクトであるため)、その後、あなたがさえ割り当てを行うことが許可されていません。

let numbers: AnyObject = [11, 22, 33] // error: contextual type 'AnyObject' cannot be used with array literal 

あなたはしかし、Anyにキャストすることができます

let numbers: Any = [11, 22, 33]  
numbers.dynamicType // 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はObjective-Cのように厄介なobject does not recognises selector例外をスローするのではなく、nilという値を正常に返します。これが良いか悪いかである場合は、Objective-Cのメソッドを使用しようとした場合、その後、あなたはよ、プロパティのような方法で、:)

更新 は、上記のプロパティだけのために働くようで議論したままであり、認識されていないセレクタの問題に遭遇:

import Foundation 

@objc class TestClass: NSObject { 
    @objc var someProperty: Int = 20 
    @objc func someMethod() {} 
} 

let numbers: AnyObject = [11, 22, 33] 
numbers.lowercaseString    // nil 
numbers.someMethod      // nil 
numbers.someMethod()     // unrecognized selector 
numbers.stringByAppendingString("abc") // unrecognized selector 
+0

素晴らしい発見と素晴らしい答えです。私の答えは、Foundationがインポートされたと仮定しています。純粋な迅速な説明をありがとう! – JAL

関連する問題