失敗可能イニシャライザにおけるプロパティ初期化の必要性

Swift プログラミング

Swift では初期化不能と判断したときに nil を返せるイニシャライザがありますが、構造体とクラスとで、ストアドプロパティの初期化の仕方(必要性)に差がある様子でした。


Swift言語 には失敗可能イニシャライザ (Failable Initializer) という、初期化ができなかったときにnil を返せるイニシャライザがあります。

struct MyClass {
	
	init?() {

	}
}

引数やその他の条件によって、自分自身の初期化ができなかった場合に限ってreturn nil を実行することで結果として nil を返せるのですが、構造体とクラスとで、どの段階で nil を返すことができるかが違ってくる様子でした。

Optional<Self> を返すinit? の他にもImplicitlyUnwrappedOptional<Self> を返せるinit! があります。

構造体で nil を返すとき

構造体で失敗可能イニシャライザを定義するときは、ストアドプロパティの初期化が完了していない段階でも、初期化不可能であると確定した段階で自由にreturn nil できる様子でした。

struct MyClass {
	
	var value:Int
	
	init?() {

		// ストアドプロパティの初期化前でも失敗できます。
		return nil
	}
}

もちろん初期化可能な場合には、全てのストアドプロパティを初期化してイニシャライザの処理を終える必要があります。

クラスで nil を返すとき

クラスで失敗可能イニシャライザを定義するときは、初期化不可能であっても必ず、ストアドプロパティになんらかの値を設定してからreturn nil を実行しないといけない様子でした。

struct MyClass {
	
	var value:Int
	
	init?() {

		// ストアドプロパティを何らかの値で初期化前してから失敗する必要があるようです。
		value = 0
		return nil
	}
}

初期化できない場合はnil を返すので、その後でストアドプロパティが使用されることはないはずなのですが、どうしてクラスがこのような仕様になっているかは分かりません。

ちなみにストアドプロパティの初期化を追えないままnil を返そうとすると、次のようなビルドエラーになります。

All stored properties of a class instance must be initialized before returning nil from an initializer

クラスがファイナルクラスであっても同様です。