Swift には、不特定な型を扱うための特別なタイプエイリアスがあります。

  • AnyObject は、あらゆるクラス型のインスタンスを表現できます。
  • Any は、関数型を含め、あらゆるすべての型のインスタンスを表現できます。
NOTE
あきらかに必要な場合にのみ、Any と AnyObject を使用します。コードで扱う型については、明確であるほうが常に望ましいです。

AnyObject

Cocoa API を扱う場合に、[AnyObject] の型の配列、つまりあらゆる型の値の配列を受け取る場合があります。Objective-C は明確に型付けされた配列を現在はサポートしていますが、古いバージョンではこの機能はありませんでした。ですが、API について把握している情報から、配列が含むオブジェクトの型について自信を持っている場合もあります。

このような状況では、配列の各アイテムを AnyObject よりも明確な型にダウンキャストするために、オプショナルアンラップする必要なく、強制バージョンの型キャスト演算子 (as!) を使うことができます。

次の例では、[AnyObject] 型の配列を定義し、Movie クラスの 3 つのインスタンスを生成しています。

let someObjects: [AnyObject] = [
    Movie(name: "2001: A Space Odyssey", director: "Stanley Kubrick"),
    Movie(name: "Moon", director: "Duncan Jones"),
    Movie(name: "Alien", director: "Ridley Scott")
]

この配列には Movie インスタンスのみ含んでいることがわかっているため、強制バージョンの型キャスト演算子 (as!) でダウンキャストして、オプショナルでない Movie に直接アンラップすることができます。

for object in someObjects {
    let movie = object as! Movie
    print("Movie: \(movie.name), dir. \(movie.director)")
}
// Movie: 2001: A Space Odyssey, dir. Stanley Kubrick
// Movie: Moon, dir. Duncan Jones
// Movie: Alien, dir. Ridley Scott

このループのさらに短い形式では、配列の各アイテムをダウンキャストするのではなく、配列の someObjects を [Movie] の型にダウンキャストしています。

for movie in someObjects as! [Movie] {
    print("Movie: \(movie.name), dir. \(movie.director)")
}
// Movie: 2001: A Space Odyssey, dir. Stanley Kubrick
// Movie: Moon, dir. Duncan Jones
// Movie: Alien, dir. Ridley Scott

Any

次は、関数型やクラスでない型を含む、様々な型を扱う Any を使用している例です。例では、Any型の値を持つことができる配列 things を生成しています。

var things = [Any]()

things.append(0)
things.append(0.0)
things.append(42)
things.append(3.14159)
things.append("hello")
things.append((3.0, 5.0))
things.append(Movie(name: "Ghostbusters", director: "Ivan Reitman"))
things.append({ (name: String) -> String in "Hello, \(name)" })

配列 things は、Int 値、Double 値、String 値、(Double, Double) 型のタプル、映画 “Ghostbusters”、そして String 値を受け取って別の String 値を返すクロージャ式を含んでいます。

Any や AnyObject であるとだけわかっている定数や変数の明確な型を明らかにするために、switch 文のケースで is や as 演算子を使用することができます。次の例では、配列 thingsにあるアイテムを繰り返し処理し、switch 文で各アイテムの型を問い合わせています。switch 文のケースで、値を出力できるよう特定の型の定数にマッチした値をバインドしています。

for thing in things {
    switch thing {
    case 0 as Int:
        print("zero as an Int")
    case 0 as Double:
        print("zero as a Double")
    case let someInt as Int:
        print("an integer value of \(someInt)")
    case let someDouble as Double where someDouble > 0:
        print("a positive double value of \(someDouble)")
    case is Double:
        print("some other double value that I don't want to print")
    case let someString as String:
        print("a string value of \"\(someString)\"")
    case let (x, y) as (Double, Double):
        print("an (x, y) point at \(x), \(y)")
    case let movie as Movie:
        print("a movie called \(movie.name), dir. \(movie.director)")
    case let stringConverter as String -> String:
        print(stringConverter("Michael"))
    default:
        print("something else")
    }
}

// zero as an Int
// zero as a Double
// an integer value of 42
// a positive double value of 3.14159
// a string value of "hello"
// an (x, y) point at 3.0, 5.0
// a movie called Ghostbusters, dir. Ivan Reitman
// Hello, Michael

Portions of this page are translations based on work created and shared by Apple and used according to terms described in the Creative Commons Attribution 4.0 International License.