is
および as
演算子で実装されます。これらの 2 つの演算子は、値の型をチェックしたり、値を別の型にキャストしたりするためのシンプルで表現力豊かな方法を提供します。MediaItem
という新しい基本クラスを定義します。このクラスは、デジタルメディアライブラリに表示されるあらゆる種類のアイテムの基本的な機能を提供します。具体的には、String
型の name
プロパティと init(name:)
イニシャライザを宣言しています。(全ての映画と曲を含む全てのメディアアイテムに名前があると想定しています)MediaItem
の 2 つのサブクラスを定義します。最初のサブクラスの Movie
は、映画または映画に関する追加情報をカプセル化します。これは、対応するイニシャライザを使用して、基本クラスの MediaItem
の上に director
プロパティを追加します。2 番目のサブクラスの Song
は、基本クラスの上に artist
プロパティとイニシャライザを追加します:Movie
インスタンスと 3 つの Song
インスタンスを含む library
という定数配列を作成します。library
の配列の型は、初期化時に使用する配列リテラルの内容から推論できます。Swift の型チェックは、Movie
と Song
が MediaItem
という共通のスーパークラスを持っていることを推論できるため、library
配列が [MediaItem]
型だと推論できます。library
に保存されているアイテムは、依然として裏側では Movie
および Song
インスタンスです。ただし、この配列の内容を反復処理すると、返されるアイテムは Movie
や Song
ではなく MediaItem
になります。それらを本来の型として使用するには、型を確認するか、下記で説明するように別の型に_ダウンキャスト_する必要があります。is
)を使用します。型チェック演算子は、インスタンスがそのサブクラス型の場合は true
を返し、そうでない場合は false
を返します。library
配列内の Movie
および Song
インスタンスの数をカウントする 2 つの変数 movieCount
と songCount
を定義しています:library
配列内の全てのアイテムを繰り返します。for-in
ループの各ループでは、item
定数に配列内の次の MediaItem
を設定します。item is Movie
は、現在の MediaItem
が Movie
インスタンスの場合は true
を返し、そうでない場合は false
を返します。同様に、item is Song
は、アイテムが Song
インスタンスかどうかをチェックします。for-in
ループの最後で、movieCount
と songCount
の値には、各型の MediaItem
インスタンスがいくつ見つかったかをカウントしています。as?
または as!
) を使用してサブクラス型への_ダウンキャスト_を試みることができます。as?
は、ダウンキャストしようとしている型のオプショナルの値を返します。強制形式の as!
は、ダウンキャストと強制アンラップを同時に試みます。as?
) を使用してください。この形式の演算子は常にオプショナルの値を返し、ダウンキャストが不可能な場合、値は nil
になります。これにより、ダウンキャストが成功したかどうかを確認できます。as!
) は、ダウンキャストが常に成功することが確実な場合にのみ使用してください。不適切なクラス型にダウンキャストしようとすると、実行時エラーを引き起こしします。library
内の各 MediaItem
を繰り返し処理し、各アイテムの適切な説明を出力します。これを行うには、MediaItem
としてだけでなく、実際の Movie
または Song
として各アイテムにアクセスする必要があります。これは、説明で使用する Movie
または Song
の director
または artist
のプロパティにアクセスできるようにするために必要です。Movie
または Song
のいずれかの可能性があります。各項目に使用する実際のクラスは事前にわからないため、条件付き形式の型キャスト演算子(as?
)を使用して、ループの中で毎回ダウンキャストしてチェックすることが適切です:Movie
としてダウンキャストしようとしています。item
は MediaItem
インスタンスなので、それが実際は Movie
インスタンスの可能性があります。同様に、それが Song
インスタンスの可能性もあれば、単に基本クラスの MediaItem
インスタンスの可能性もあります。このように不確かなため、as?
型キャスト演算子の形式でサブクラス型にダウンキャストしようとしたときに、オプショナルの値を返します。item as? Movie
の結果は Movie?
または"オプショナルの Movie
"です。Song
インスタンスに適用すると、Movie
へのダウンキャストが失敗します。これに対処するために、上記の例では、オプショナルバインディングを使用して、オプショナルの Movie
に実際に値が含まれているかどうか(つまり、ダウンキャストが成功したかどうか)を確認します。このオプショナルバインディング、"if let movie = item as? Movie
"は、次のように読むことができます:Movie
を movie
という新しい一時定数に設定します」Movie
のプロパティを使用して、その Movie
インスタンスの director
の名前を含む説明が出力されます。同様に、Song
インスタンスをチェックし、ライブラリで Song
が見つかる度に artist
名を含む適切な説明を出力します。NOTE キャストは実際にインスタンスを変更したり、その内部の値を変更したりしません。基になるインスタンスは同じままです。キャストした型のインスタンスとして扱われ、アクセスされるだけです。
Any
は、関数型を含むあらゆる型のインスタンスを表すことができますAnyObject
は、任意のクラス型のインスタンスを表すことができますAny
および AnyObject
は、それらが提供する動作と機能が明らかに必要な場合にのみ使用してください。常にコードで使用しようとしている型を特定することをお勧めします。Any
を使用して、関数型と非クラス型を含む様々な型の組み合わせを処理する例を次に示します。この例では、Any
型の値を格納できる things
という配列を作成します:things
配列には、2 つの Int
、2 つの Double
、1 つの String
、(Double、Double)
型のタプル、映画"Ghostbusters"、および String
値を受け取り、別の String
値を返すクロージャ式、が含まれます。Any
型または AnyObject
型なことがわかっている定数または変数の特定の型を検出するには、switch
文のケースで is
または as
パターンを使用できます。下記の例では、things
配列内の項目を繰り返し処理し、switch
文を使用して各項目の型を照会します。switch
文のいくつかのケースは、一致した値を指定された型の定数にバインドして、その値を出力できるようにしています:NOTE Any 型は、オプショナルの型を含む任意の型の値を表します。Any
型の値が期待されているところにオプショナル値を使用すると、Swift は警告を出します。本当にオプショナルの値をAny
値として使用する必要がある場合は、下記に示すように、as
演算子を使用して、オプショナルをAny
に明示的にキャストします。1let optionalNumber: Int? = 32things.append(optionalNumber) // Warning3things.append(optionalNumber as Any) // No warningCopied!