Help us understand the problem. What is going on with this article?

型のキャスト (as, as?, as!) について

More than 1 year has passed since last update.

型のキャスト

はじめに型のキャストとは、演算子asを用いて変数や定数の値をより具体的な型として扱う操作です。ここではアップキャストとダウンキャストについて説明します。

アップキャスト

アップキャストとは、クラスの継承やプロトコルの準拠などの階層関係がある型どうしにおいて、
上位の型として扱う操作です。

let str = "abc"   
let any = str as Any      //String型をAny型にアップキャスト

アップキャストはコンパイル可能な場合、常にキャストに成功します。
そのため、上記のような定数(および変数)の宣言時にas演算子によってアップキャストを行う場合、
キャスト先の型として推論可能なため、型アノテーションが省略できます。

ダウンキャスト

ダウンキャストとは、クラスの継承やプロトコルの準拠などの階層関係がある型どうしにおいて、
下位の型として扱う操作です。
ダウンキャストはアップキャストと異なり、コンパイル可能な場合でもキャスト実行が失敗することがあります。
そのため、ダウンキャストの方法としてas!as?が用意されています。

as!

as!はダウンキャストの際、強制的に右辺の型にキャストをします(強制キャスト)。

let any: Any = "abc"
let str = any as! String   //String型"abc"
let num = any as! Int      //Int型にキャスト失敗(実行時エラー)

上記ではAny"abc"String"abc"にダウンキャストは成功しているものの、Int型へのダウンキャストは失敗し実行時エラーとなります。

as?

as?はダウンキャストが成功するか分からない場合に使用します。成功時はOptional型となり、キャスト失敗時はnilとなります。

let any: Any = "abc"
let str = any as? String   //Optional("abc")
let num = any as? Int      //nil

上記では Any"abc"をダウンキャストする際、成功時はOptional("abc")となり失敗時はnilとなります。

まとめ

アップキャストはコンパイル時にエラーが発見できますが、ダウンキャストはコンパイル成功時も実行時エラーとなる可能性があるため、注意する必要があります。
特にas!は値の型が保証されている場合は便利ですが、迷った場合はas?を用いることが良いかと思います。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away