7

Xcode 7.1 を使用して Swift 2.2 を開発するときに混乱する状況が 2 つあります。以下の例を参照してください。

まず、Foundation をインポートするときに、整数型 1 と文字列型 "hello" の 2 つの項目を含む testArray を宣言しました。私の質問は、なぜ Swift 型推論 testArray が Array(Any) ではなく Array(NSObject) になるのかということです。

import Foundation
let testArray = [1, "hello"] 
print(testArray.dynamicType) //testArray is Array<NSObject>

次に、import Foundation を削除すると、以下のコードをコンパイルできません。エラー メッセージは「Type of expression is ambiguous without more content」です。私の質問は、なぜ Swift がこの状況で Array(Any) への型推論を行わないのかということです。助けを求める

let testArray2 = [2, "world"]
print(testArray2) 
//can't compile, error message = "Type of expression is ambiguous without more content"
4

2 に答える 2

9
/// The protocol to which all types implicitly conform.
public typealias Any = protocol<>

Anyは、すべての型が暗黙的に準拠するプロトコルにすぎません。具体的な型自体ではありません。Swift は非具象型の配列を推論できないため、 の推論に失敗しますが、 (にブリッジすることができ、にブリッジすることができます– そしてそれらは両方とも具象型である から継承します)Anyで成功します。NSObjectIntNSNumberStringNSStringNSObject

たとえば、次のように考えてください。

protocol Foo {}
struct Bar:Foo {}
struct Baz:Foo {}

let arr = [Bar(), Baz()] // error: Type of expression is ambiguous without more context

Fooは非具象型であるため、Swift はその配列を推測できません。コンパイラに、その型をどうしたいかを明示的に伝える必要があります。

let arr:[Foo] = [Bar(), Baz()]

また、同じ動作が得られます(これは、すべてのクラスAnyObjectが暗黙的に準拠するプロトコルですが、具象型ではないためです):

class Qux {}
class Fox {}

let a = [Qux(), Fox()] // error: Type of expression is ambiguous without more context

let a1:[AnyObject] = [Qux(), Fox()] // no error

Swift が非具象型の配列を推論できない理由は、おそらく言語内の非具象型の既存の制限によるものです。現在、ほとんどの重要な操作には具象型が必要です。例として、このすばらしい Q&A を参照してください

しかし、正直に言うと、実際にの配列が必要かどうかについてもっと考えるべきですAny。の配列を持つ単一の実用的なアプリケーションは考えられません。Anyすべてが要素に暗黙的に準拠しているため、何もしないことが保証されている必要があるためです (何かである可能性のあるものに対して特定のメソッドを呼び出すことはできません)。確かに型キャストはできますが、そもそも捨てた型安全性を取り戻すことに何の意味があるのでしょうか?

できる限りタイプ固有にする必要があります。値のラッパーを作成できます。これはstruct、いくつかのプロパティをラップする単純なものか、非具象型を疑似具象型にラップするための型消去のいずれかです。少なくとも、配列要素が準拠する独自のプロトコルを作成することを検討する必要があります。

于 2016-05-04T10:52:25.227 に答える
3

の配列を自動認識しないためAny

次のように定義すると機能します

let testArray2 :[Any] = [2, "world"]

Foundationライブラリは をインポートします。これにより、 がとNS APIに自動的に変換2され、自動的に の配列に変換されます。NSNumber"world"NSStringNSObject

于 2016-05-04T10:10:43.873 に答える