Edited at

structでConvenience Initializerを追加したい、しかしMemberwise initialiserは残したい時の書き方

More than 3 years have passed since last update.

GetWild退勤的なセンサーアプリを簡単に作れるフレームワークを作ったのでiPhoneに歯痛を心配されたり色々する

で得た知見シリーズ

structは何もしなくても勝手にイニシャライザを作ってくれて、それをMemberwise initialiserと呼ぶ

struct Hoge {

let foo: String
let bar: String
}

Hoge(foo:"a", bar:"b")

のだけれど、structに自前のイニシャライザを追加してしまうとその時点でMemberwise initialiserが自動生成されなくなってしまい、辛い思いをする事がある。

struct Hoge {

let foo: String
let bar: String

init(properties: Dictionary<String, AnyObject>) {
foo = properties["foo"] as! String
bar = properties["bar"] as! String
}

// 辛いという思い
init(foo: String, bar: String) {
self.foo = foo
self.bar = bar
}
}

こういう時はextensionでConvenience Initializerを書くとMemberwise initialiserの自動生成が残る

struct Hoge {

let foo: String
let bar: String
}

extension Hoge {
init(properties: Dictionary<String, AnyObject>) {
self.init(
foo : properties["foo"] as! String,
bar : properties["bar"] as! String
)
}
}

Hoge(foo:"a", bar:"b")

Hoge(["foo":"a", "bar":"b"])

とは言えこれはこれで微妙にあれなので良い感じになってほしい。

欲を言えば、個別のstructではなく共通のprotocol extensionにこういうinitWithDictionary/toDictionary的なものを持たせたかったのだけれど、それはそれで辛い感じになったのでstructで我慢した方が良いという結論に至った。


参考にしたもの

http://stackoverflow.com/questions/34728518/swift-can-i-call-a-struct-default-memberwise-init-from-my-custom-init-method