キャンペーンの今のうちに是非!!↓


⇒「ひろゆき『1%の努力』を無料で見る方法

【Swift奮闘記ep28】型のキャスト後半(Any型とAnyObject型、プロトコルのキャスト)

IPhoneアプリ作成Swift奮闘記

この本を見ながら進めてる↓

前回⇒「【Swift奮闘記ep27】型のキャスト前半(アップキャスト、ダウンキャスト、型のチェック)

前回のアップキャスト、ダウンキャストは理解できた方だと思っているのでこの調子で後半戦もこなしていきたい!

ではさっそく!

Any型とAnyObject型

Swiftではインスタンスをより抽象的に扱うためAny型とAnyObject型というのが用意されている。

今まではインスタンスを、「ある特定の型のインスタンス」として扱ってきたが、Any型とAnyObject型を使う事によって「特に決まっていないが、何かしらの型のインスタンス」として扱う事が出来る。

より抽象的な表現をすることができるようになるのだ。(果たしてそれがどんな意味を成すのか。乞うご期待。)

Any型

クラス、ストラクチャ、列挙型、および関数型のインスタンスを抽象化できる型がAny型である。

→変数宣言や定数宣言の型注釈、関数の引数・戻り値の型指定などに使用できる。

実際に見ていこう。


Any型の変数を定義してそれにInt型の20を代入する。

代入するものはInt型だがAny型の変数に代入された瞬間にAny型の値として扱われる。

さらにAny型はどのような型も代入できるので以下のようにString型を代入しなおすことも可能である。


さらに配列をAny型に指定すれば、様々な型が混ざったArray型のインスタンスが生成される。


万能Any型である。

AnyObject型

Any型が型に対して抽象化するもの、に対してAnyObject型はクラスのインスタンスを抽象できる型である。

実際に見てみよう。

ダウンキャストの解説で使ったコードを使って説明する。


まずはFood、Noodle、Curry型を定義する。

次に、AnyObject型の変数anyFoodにNoodleクラスのインスタンスを代入してみる。

さらにAnyObject型の変数anyFoodにCurryクラスのインスタンスも代入する。


AnyObject型なのでNoodleもCurryも代入できるんだけど、プロパティが利用できない。(利用するにはどうすればいいんだろうか・・・)


name,spicyプロパティどちらもエラーになる。

型のチェックも可能

配列、for文、if文を組み合わせて、型のチェックを行う。


for文によってどんどん変数anyに代入されていき、if文でInt型かどうかのチェックが行われ、Int型だとappendで配列に入れるわけだ。

さらにInt型であることを確認してからInt型の配列numbersに入れるのでエラーになることは無いから、強制的なアンラップ(any as! Int)で代入する。

Any型もAnyObject型も有能な機能で、iOSアプリ開発では使用場面は多いようだからしっかり覚えておこう。

いまのところ具体的にどの場面で使うかわからんけどね

プロトコルのキャスト

型のキャストはプロトコルにも使用することができる。

特定のインスタンスを「あるプロトコルに準拠した、なんらかのインスタンス」に抽象化することができる。

言葉で言われても意味がわからないので、先へ進む。


Drinkというプロトコルでvolumeを定義している。つまりDrinkプロトコルに準拠したばい、変数volumeを使わなきゃいけないってことだったよね。プロトコルを忘れた人は「【Swift奮闘記ep19】プロトコル前半(プロトコルの定義と準拠、プロパティ・メソッドの定義)」へゴーバック!

アップキャスト:プロトコルに準拠したクラスからプロトコルにキャストすること(今回の場合はCoffeからDrinkへ)

ダウンキャスト:プロトコルからプロトコルに準拠したクラスにキャストすること(今回の場合はDrinkからCoffeeへ)

次はアップキャスト、ダウンキャストのコードだが、型のチェックからの強制的なダウンキャスト(as!)を行なっている。


最初見たときはとてもわかりづらかったんだけど、一行目でCoffeeクラスのインスタンスをDrink型の定数に代入する。

この作業がアップキャスト、と書いてあるが、ただ代入しただけでなんでアップキャストなんだろうという疑問。as使わないのかな。

Coffeeクラスのインスタンスだが本来ならbeanプロパティを使えるところだが、Drink型の定数に入れてしまったがためにbeanは使えなくなっている、ということだ。volumeしか使えない状態。

if文で「定数anyDrinkの中身はCoffee型だよね?」とチェックするわけである。

本来はCoffeeクラスのインスタンスであるため、型チェックはtrue。つまり強制的なダウンキャストが成功。

それでやっとCoffeeクラスのプロパティbeanが使えるようになったっていう流れ。

さらに以下のコードはAnyObject型というのを用いてアップ・ダウンキャストを行なっている。


アップキャストを2度しているのがお分かりだろうか。

CoffeeからDrinkへアップキャスト。

さらにDrinkからAnyObjectへアップキャストしている。

その後、AnyObjectからDrinkへ型のチェックからの強制的なダウンキャストしている。

これさらにダウンキャストすればbeanを使えるってことかな。

最後に

これにて「Swiftの発展的な文法」が終わりだ。

やっと文法の勉強が終わったので、次回からは実戦的な、よりiOSアプリ開発に近い事を学んでいけるんではないかと思っている。

さらにわけわからなくなりそうだが、わからなくなったら復習したりしてなんとか進んでいきたい。

続き⇒「【Swift奮闘記ep29】iOSのSDKとフレームワーク、iOSアプリの動作の仕組み

コメント