BambooHero

iOSアプリ開発と株式投資をメインに色々書きます

[Swift] structのMemberwise Initializerを残しつつカスタムのInitializerも実装する方法

Swiftの構造体(struct)はInitializerを一つも実装しない場合にMemberwise Initializerと呼ばれるInitializerが自動で生成されます。


Structure types automatically receive a memberwise initializer if they don’t define any of their own custom initializers.

https://docs.swift.org/swift-book/LanguageGuide/Initialization.html


例えば、以下のUser型にInitializerは定義されていませんが、コンパイラが自動でMemberwise Initializerを与えてくれます。

struct User {
    let firstName: String
    let lastName: String
}


よってこのような初期化が可能です。

let user = User(firstName: "Hero", lastName: "Bamboo")


ところで、iOSアプリを実装していると、ドメインを定義したModelから、ビューに表示するためのModelであるViewModelに変換することがあります。

このようなとき、Modelの型をInitializerの引数として受け取るようにすると便利で、以下のような実装をしたりします。

struct UserViewModel {
    let firstName: String
    let lastName: String

    init(model: User) {
        self.firstName = model.firstName
        self.lastName = model.lastName
    }
}


ただし、Memberwise Initializerも残しておきたいとします。

そんなときは、以下のようにカスタムInitializerをextensionに実装しましょう。
こうすると、Memberwise Initializerを残しつつ、カスタムInitializerも実装することができます。

struct UserViewModel {
    let firstName: String
    let lastName: String
}

extension UserViewModel {
    init(model: User) {
        self.firstName = model.firstName
        self.lastName = model.lastName
    }
}


let user1 = UserViewModel(firstName: "Hero", lastName: "Bamboo")

let user2 = UserViewModel(model: user)