Swiftの初期化(Initialization)

Swiftの初期化(Initialization)

初期化(Initialization)です。初期化というのは、インスタンス生成前に実行される「プロパティの初期化」です。Swiftでは、初期化の際にプロパティに好きな値を入れることが出来るのが便利です。

ここでは、初期化とは何か?から始めて、初期化子(initializers)を使った格納プロパティの初期化、デフォルトプロパティ値、に関して詳しく説明します。

初期化(Initialization)って何?

初期化 = インスタンスを使用可能な状態にすること

初期化(Initialization)というのは、

クラスや構造体、または列挙型のインスタンスを用意する過程(プロセス)のこと

です。もう少し具体的に書くと、この「プロセス」というのは、インスタンスを使用可能な状態にするために

ことです。

初期化子(Initializers)とは?

初期化プロセスは初期化子(Initializers)を使って行います(読みは「しょきかし」です)。難しいようですが、初期化子というのは、

初期化の際に呼び出される特別なメソッド

です。

Swiftの初期化子はinit()で、これは戻り値がありません(パラメータは取ることができます)。初期化子の役割を一言で言うと、確実に新しいインスタンスをちゃんと初期化すること、です。いつ初期化するかというと、(当然ですが)インスタンスを生成する前です。

クラスは特別で、終了子(deinitializer)というものを用意することもできます。「終了」なので、クラスインスタンスを破棄する時に呼び出される特別なメソッドです。終了子に関しては、別のページで詳しく説明します。

格納プロパティの初期値をセットする

クラスや構造体の持つ全ての格納プロパティは、初期値がちゃんとセットされなければなりません。それを「初期化」と呼び、初期化はインスタンス生成前に実行される、ということを述べました。

初期化には2つ方法があって、1つが初期化子を使った初期化、もう1つはプロパティを直接初期化する方法、です。実は、後者に関しては、クラスと構造体のページでそれとなく使っています(クラスと構造体の定義構文、具体例を参照)。これには「デフォルトプロパティ値」という名前がついていますので、後で詳しく説明します。名前があると難しそうですが、やっていることは簡単です。

公式マニュアルに注意書きがありますが、格納プロパティの初期化の際には、プロパティ監視は呼びだされません。

“NOTE

When you assign a default value to a stored property, or set its initial value within an initializer, the value of that property is set directly, without calling any property observers.”

抜粋:: Apple Inc. “The Swift Programming Language”。 iBooks https://itun.es/jp/jEUH0.l

初期化子(Initializers)の定義構文

初期化子(Initializers)は、ある特定の型の新しいインスタンスが生成された時に呼び出されます。先程少し触れましたが、初期化子はメソッドの一種です。最も単純な初期化子は、パラメータを1つも取らない場合になります。

//最も単純な初期化子
init() {
  // 初期化
}

funcキーワードがついていないだけで、見た目はメソッドの構文です。

公式マニュアルでは、華氏(ファーレンハイト、Fahrenheit)を使って説明していますが、馴染みがないので摂氏(セルシウス、Celsius)を使います。デジャヴかと思ったら、前にも同じケースがありましたね。

// 摂氏
struct Celsius {
    var temperature: Double
    init() {
        temperature = 0.0
    }
}
var c = Celsius()
print("デフォルト温度は摂氏\(c.temperature)度です")
//"デフォルト温度は摂氏0.0度です"と表示

パラメータ無しの初期化子init()を使って、格納プロパティのtemperatureを初期化しています。華氏の場合は32.0という値が、摂氏0度だそうですが、慣れないと全然感覚がつかめませんね。

デフォルトプロパティ値(Default Property Values)

上記のケースだと、まずプロパティtemperatureを宣言し、初期化子内部で初期値をセットする、という2段構えの初期化です(厳密に言うと、初期化しているのは初期化子ですが)。

最初に「初期化には2つ方法がある」と書きましたが、もう1つの方法で上記のケースを書き直すこともできます。もう1つの方法では、初期化子を使わずに、直接プロパティに初期値を与えます(デフォルトプロパティ値)。変数宣言の際に、同時に初期化するのと全く同様です。

// プロパティを直接初期化
struct Celsius {
    var temperature: Double = 0.0
}

一応明示的にDoubleを指定しましたが、省略しても構いません(型推論)。

このケースでは、初期化子init()自体がパラメータを持ってません。したがって、プロパティに与える値は、直接だろうが初期化子内部だろうが、手で与えることに変わりありません。こういう場合は、デフォルト値を与えた方がすっきりして簡単です。

一方で、初期化子にパラメータを持たせて、動的に初期化したい場合は、初期化子経由でないと無理ですね。そのような「初期化のカスタマイズ」を次のセクションで詳しく見ていこうと思います。

まとめ

  • 初期化(Initialization)とは「インスタンスを使用可能な状態にすること」。例)プロパティに初期値をセット
  • 初期化は初期化子(Initializers)init()で行う
  • 初期化子は戻り値がないが、パラメータを取ることが出来る。func指定がない特別なメソッド
  • プロパティの初期値が固定なら、デフォルトプロパティ値を与えて初期化することが出来る