同一ファイル内のエクステンションでのメンバーワイズイニシャライザ
Same-file memberwise initializer extensions
このダイジェストはClaude Opus 4.7 / 4.8によって生成されたものです(License)。原文はこちら↗。
01 何が問題だったのか
構造体(struct)では、stored property の一覧からメンバーワイズイニシャライザが自動的に合成されます。しかし、このイニシャライザを public(や package)として公開したい場合、これまではその構造体の本体(base declaration)内に直接書くしかありませんでした。
// ✅
public struct Post {
public var title: String
public init(title: String) { self.title = title }
}
同じイニシャライザをエクステンション側に書こうとすると、合成されるメンバーワイズイニシャライザと衝突してコンパイルエラーになります。
public struct Post {
public var title: String
}
extension Post {
// 🛑 invalid redeclaration of synthesized memberwise 'init'...
public init(title: String) { self.title = title }
}
この制約は、コードを整理するうえでの単なる不便にとどまりません。マクロで構造体を生成する場合には、生成された構造体のメンバーワイズイニシャライザを公開する手段がなくなってしまいます。マクロが生成する型の本体にイニシャライザを書き加えることはできないため、公開したければエクステンションに書くしかありませんが、それが上記のエラーになるからです。
@Draftable public struct Post {
public var title: String
// 生成される型:
public struct Draft {
public var title: String?
}
}
extension Post.Draft {
public init(title: String?) { self.title = title } // 🛑
}
さらに、マクロが生成した型を、合成イニシャライザと同じシグネチャの要件を持つプロトコルに適合させることもできません。合成されたイニシャライザは public ではないため、要件を満たせないからです。
public protocol TitleInitializable {
init(title: String?)
}
// 🛑 Initializer 'init(title:)' must be declared public...
extension Post.Draft: TitleInitializable {}
02 どのように解決されるのか
SE-0546 では、メンバーワイズイニシャライザを構造体と同じファイル内のエクステンションで定義できるようになります。
public struct Post {
public var title: String
}
extension Post {
// ✅
public init(title: String) { self.title = title }
}
具体的には、合成されるメンバーワイズイニシャライザと区別がつかないイニシャライザ、つまり同じ引数ラベルと型を同じ順序で持つイニシャライザを、制約のない(unconstrained)同一ファイル内のエクステンションで定義した場合、自動合成されるイニシャライザが抑制され、手書きした側が使われます。これにより、アクセス修飾子を public や package に引き上げたイニシャライザをエクステンションに置けるようになります。
この仕組みはメンバーワイズイニシャライザだけでなく、引数のないデフォルトの init() にも適用されます。stored property がすべてデフォルト値を持つ構造体では、メンバーワイズイニシャライザに加えて引数のない init() も合成されますが、この init() を公開したい場合も同じように同一ファイル内のエクステンションに書けます。
public struct Settings {
public var isEnabled = false
}
extension Settings {
// ✅
public init() {}
}
「同一ファイル内」に限定されているのは、Codable や Hashable の適合を同一ファイル内のエクステンションで合成できるのと同じ考え方です。イニシャライザの定義がどのファイルにあるか探し回らずにコードを読めるようにするための制限です。
マクロで生成した型に対しても、生成された型の定義と同じファイルにエクステンションを書けば、そのメンバーワイズイニシャライザを公開したり、対応するプロトコルへ適合させたりできるようになります。
この変更は追加的(additive)で、これまでコンパイルできなかったコードがコンパイルできるようになるだけです。ソース互換性やABI互換性への影響はなく、自由に採用・不採用を切り替えられます。
03 今後の見通し
メンバーワイズイニシャライザについては、これまでにもさまざまな拡張が議論されてきました。たとえば、メンバーワイズイニシャライザを明示的に合成させる仕組みや、長いイニシャライザを簡潔に書くための短縮記法などがフォーラムで提案されています。
SE-0546 はあくまでメンバーワイズイニシャライザを同一ファイル内のエクステンションに置けるようにするだけの変更であり、こうした今後の発展を妨げるものではないとされています。ただし、これらはあくまで将来の構想であり、実現が約束されているわけではありません。