Swiftのas! 演算子

LINEで送る
Pocket

Swiftではキャストとして as を使います。
今まではダウンキャストに(派生クラスへのキャスト)も使用していました。
オプショナル型へのキャスト(ダウンキャストに失敗したらnilを返す)として as? があります。

オプショナル型の変数を強制的にアンラップ(オプショナルでなくする)するのに変数に ! をつけますが、Swift1.2では強制的にダウンキャストするのに as!が導入されました。

Swift 1.2 separates the notions of guaranteed conversion and forced conversion into two distinct operators. Guaranteed conversion is still performed with the as operator, but forced conversion now uses the as! operator. The ! is meant to indicate that the conversion may fail. This way, you know at a glance which conversions may cause the program to crash.Swift Blog

as! 演算子

Swift1.2以前では、as演算子は変換される式や型によって、2種類の変換を実行することができました。

  • 保証された変換はある型から別の型に変換するときにSwiftコンパイラで成功が保証できるような変換です。例えばアップキャスト(あるクラスからその基底クラスへの変換)やリテラル型の明確化(例:1 as Float)がこれにあたります。
  • 強制された変換は別の型に変換するときにSwiftiコンパイラで安全性を保証できない場合で実行時エラーを引き起こす可能性があります。例えば、あるクラスからその派生クラスへのダウンキャストがこれにあたります。

Swift1.2ではこの保証変換と強制変換を別々の演算子で区別することになりました。保証変換は今までどおりas演算子を使用しますが、強制変換はas!演算子を使用することになりました。!は変換が失敗するかもしれないということを意味します。これによってプログラムをぱっと見でクラッシュする可能性があるかどうかを判断できます。

次の例ではこの変更を示しています。

class Animal {}
class Dog: Animal {}

let a: Animal = Dog()
a as Dog			// エラーが発生します:  "'Animal is not convertible to 'Dog';
				// ... did you mean to use 'as!' to force downcast?"

a as! Dog		// 強制ダウンキャストが許されます

let d = Dog()
d as Animal		// アップキャストは成功します

変数の後ろにつく!?と変換演算子as!as?の類似性に注目してみましょう。

class Animal {}

class Cat: Animal {}

class Dog: Animal {
	var name = "Spot"
}

let dog: Dog? = nil
dog?.name		// nilとなります
dog!.name		// 実行時エラーを引き起こします

let animal: Animal = Cat()
animal as? Dog	// nilとなります
animal as! Dog	// 実行時エラーを引き起こします

Swiftでは、!は「エラーが発生する可能性がある」、?は「nilになる可能性がある」と覚えるのが簡単です。

LINEで送る
Pocket

Tags:

コメントを残す