型キャストとは
キャスト
とは変数や定数の方をより具体的かつ汎用的な型として扱うことを指します。
例えば、Any型
だった変数をString型
として扱ったり、逆にString型
をAny型
として扱ったりすることを指します。
キャストの種類
キャストにはアップキャスト
と、ダウンキャスト
のに種類が存在します。
アップキャストとダウンキャストの違いは、より汎用的な型として扱うのか、具体的な型として扱うかという違いです。
アップキャストとは
アップキャスト
はより汎用的な値(より広いくくり)として扱う場合に使います。
アップキャストを扱う場合はas
を使用します。それではコードを書いてみます。
let string: String = "sample" //String型
let any: Any = string as Any //String型からAny型へアップキャスト
このようにアップキャストしたい値 as アップキャストする型
という形式で書くことでアップキャストを行うことができます。
ダウンキャストとは
ダウンキャスト
はより具体的な型として扱うことを指します。
ダウンキャストの場合は必ずしも成り立つというわけではありません。失敗する可能性を含んでいます。
なので文法としても失敗を含む前提のものとなっているのを理解しておきましょう。
ダウンキャストの書き方はas?かas!
を使う2種類の方法があります。
as?を使ったダウンキャスト
それではコードを書いてみます。
as?
を使った書き方は以下の通りです。
let any: Any = "sample" as Any
let string = any as? String //Optional("sample")
let int = any as? Int //nil
上記の例の3行目でInt型へダウンキャストをしようとしますが、"sample"はInt型にはなりえないので失敗します。その場合は値がnilです。
このように失敗した場合にnilとなるのがas?の特徴です。
それに付随して、2行目を見てみると、こちらはString型へのダウンキャストが成功していますが、値はString型のオプショナル型となっています。
これは失敗する可能性があるので結果がオプショナル型になります。(オプショナル型とは簡潔にいうとnilを許容するということです)
このようにas?を使用したダウンキャストは結果がオプショナル型となり失敗した場合に結果はnilとなります。
as?を使ったダウンキャストまとめ
①結果がオプショナル型となる
②失敗した場合に結果nilとなる
as!を使ったダウンキャスト
as!
を使ったダウンキャストは以下のように書きます。
let any: Any = "sample" as Any
let string = any as! String //"sample"
let int = any as! Int //実行時エラー
書き方自体はas?の場合と特にそこまで変わってはいませんが、結果が異なります。
2行目がas?の場合にはオプショナル型だったのがString型になっています。
加えて、3行目で実行時エラーとなっています。
オプショナル型が分かる人にはおおよそ検討がついたかもしれませんが、as!を使った場合には結果が強制的にアンラップされて、結果がオプショナル型にならない代わりに、失敗した場合に実行時エラーとなり、アプリがクラッシュします。
as!を使ったダウンキャストを強制キャストといいます。
as?を使ったダウンキャストまとめ
①結果がオプショナル型にはならない
②失敗した場合に実行時エラーとなる
as?とas!のどちらを使うべきか
as?
とas!
を使ったダウンキャストの方法をしてきました。
as?は安全である代わりに、失敗したときの処理を書かなければいけません。
対してas!は失敗したときの処理を書かなくていい代わりに、実行時にエラーの危険性があります。
どちらも一長一短の特徴を持っていると言えますが、個人的には基本的には安全であるas?を使うのがいいかと思います。
危険なパターンとしては[Fix]
を押してみたら解決したので大丈夫だ!って思い、実行したら実行時エラーになってしまうパターンです。ここまで読んでいただいた人はなぜダメなのかもう分かるかと思いますが、このようにしてas!を使うのは不安定なコードになりやすいので注意が必要ですね。
まとめ
この記事を投稿するときに参考にさせていただいた記事を紹介しておきます。
https://fukatsu.tech/swift-cast
今回は、型キャスト
に関してまとめました。
型キャストはswiftの基本事項ですが、理解せずに扱うと思わぬエラーに遭遇したり、とりあえず記述している状態に陥りやすいので明確に理解する必要があると私は思います。
なので、今回は自身の学びを深めるために他の記事を参考にしながら整理し、投稿させて貰いました。是非参考にしてください!