この記事ではSwift
の基本ある、キャスト
についての基本事項を解説していきます。
プログラミングが初心者も、他の言語をやっていてSwift
は初心者という人にもわかるように説明していきたいと思います。
サンプルコードも交えながら説明していきますので、Playground
を使って実際に手を動かしながら行えると効率よく学習できるかなと思います。
実行環境
MacOS Mojave バージョン10.14.3
Xcode Version 10.2.1
Swift version 5.0.1
型キャストとは
キャスト
とは変数や定数の型を、より具体的な型や汎用的な型として扱うことです。
例えば、Any型
であった変数や定数をInt型
として扱ったり、逆にInt型
だった変数や定数をAny型
として扱うような操作です。
キャスト
にはアップキャスト
とダウンキャスト
の2種類があります。
アップキャスト
とダウンキャスト
の違いは、より汎用的な型
として扱うのか、具体的な型
として扱うかという違いです。
それではそれぞれ説明していきます。
アップキャストとは
アップキャスト
は、より汎用的な型
として扱うことを指します。
例えば、たかし君は東京都民です。
東京都民であるならば、日本人でもあるので、日本人としての振る舞いもします。
このような東京都民から日本人というように、より広いくくりとして扱う場合に、アップキャスト
を使います。
ではコードで見ていきましょう。
アップキャスト
を行うときにはas
を使用します。
let string: String = "sample"
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型のオプショナル型
となっています。
これは失敗する可能性があるので結果がオプショナル型
になります。
オプショナル型
に関してはこちらの記事で解説していますので、まだ理解できていない人はこちらを参考にしてください。
このようにas?
を使用したダウンキャスト
は結果がオプショナル型
となり失敗した場合に結果はnil
となります。
- 結果が
オプショナル型
となる - 失敗した場合に結果
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!
を使うほうがむしろ好ましい場面もいくつかあります。
例えばTableView
でTableViewCell
を呼び出す際の処理です。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! TableViewCell
return cell
}
ここでは、処理が失敗しない前提というのと、万が一失敗したとしても開発環境の時点でクラッシュしたほうが気づきやすいという利点を考慮してas!
と書くようにしています。
上記の例のように、僕らのチームでは、UI周りのパーツのインスタンス化する処理ではas!
を使うようにしています。
このように、両方の特徴をしっかり理解した上で、チーム内などで基準を設けたりして適切な方を選ぶことが重要だと思います。
以下はやってはいけないダメな例です。
なんか修正しろってメッセージが出てたから「Fix」を押してみたら解決したので大丈夫だ!って思って実行したら実行時エラーになってしまいます。
ここまで読んでいただいた人はなぜダメなのかもう分かるかと思いますが、このようにしてas!
を使うのは不安定なコードになりやすいので注意です。
まとめ
今回は、型キャスト
に関してまとめていきました。
型キャスト
はSwift
の基本事項なのでしっかり押さえておきましょう。
Swift
の入門記事に関してはこちらにまとめていますので参考にしてみてください。