LoginSignup
1
2

More than 1 year has passed since last update.

[Swift]構造体のメンバーごとの初期化子(initializer)はいつ使用できるのか。

Posted at

※この記事はSwift by Sundellの内容を日本語に翻訳したものです。

Swiftでは、構造体として定義された型は、コンパイラーによって合成されたデフォルトの初期化子(いわゆる「メンバーごとの初期化子」)を自動的に取得します。これは、コンパイラーが指定された構造体のメンバー(つまり、その格納されたプロパティ)に基づいて生成するためです。

たとえば、 nameプロパティとpreferencesプロパティを持つ User構造体を定義した場合、メンバーごとの初期化を使用して、これら2つのプロパティの値を渡すだけでインスタンスを作成できます。

struct User {
    var name: String
    var preferences: Preferences
}

let user = User(name: "John", preferences: Preferences())

一方、計算されたプロパティは、コンパイラがメンバーごとの初期化子を合成するときに完全に無視されます。したがって、初期化子を追加しても、以前と同じように上記の初期化子を使用し続けることができます。

struct User {
    var name: String
    var preferences: Preferences
    var icon: Icon { .user }
}

let user = User(name: "John", preferences: Preferences())

Swift 5.1以降、メンバーごとの初期化子はデフォルトのプロパティ値も考慮に入れます。つまり、preferencesプロパティにデフォルト値を指定すると、nameを渡すだけでUserインスタンスを作成できるようになります。

struct User {
    var name: String
    var preferences = Preferences()
}

let user = User(name: "John")

クールな点の1つは、型にprivateプロパティがある場合でも、それらのプロパティに次のようなデフォルト値がある限り、型のメンバーごとの初期化子を使用し続けることができることです。

struct User {
    var name: String
    private var preferences = Preferences()
}

let user = User(name: "John")

ただし、privateプロパティにデフォルト値がない場合は、そのタイプのイニシャライザを手動で作成する必要があります。これにより、そのプロパティの値を外部から挿入できるようになります。

struct User {
    var name: String
    private var preferences: Preferences

    init(name: String, preferences: Preferences = .init()) {
        self.name = name
        self.preferences = preferences
    }
}

let user = User(name: "John")

// ↓でもOK
let user = User.init(name: "John")

ただし、メンバーごとのイニシャライザーのアクセスレベルがinternalより高くなることはありません。つまり、タイプが定義されているモジュール内でのみ内部的に使用できます。

これは最初は奇妙な制限のように思えるかもしれませんが、データの内部構造に縛られることなく、常にパブリック消費用の明示的なAPIを設計する必要があるため、メリットがあります。

したがって、要約すると、次の場合に構造体のメンバーごとの初期化子を使用できます。

  • そのすべてのメンバーが表示されるか、デフォルト値がある場合。
  • 構造体が定義されているのと同じモジュール内にインスタンスを作成している場合。

他のすべてのケースでは、少なくとも今のところ、初期化子を手動で実装する必要があります。

元の記事

When can a struct’s memberwise initializer be used? Swift by Sundell

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2