デフォルトで、Swiftの構造体のメンバーごとの初期化子をパブリックにするにはどうすればよいですか?


164

私は構造体を定義する迅速なフレームワークを持っています:

public struct CollectionTO {
    var index: Order
    var title: String
    var description: String
}

ただし、ライブラリをインポートする別のプロジェクトからの暗黙のメンバーごとの初期化子を使用することはできません。エラーは、「CollectionTO」にはアクセス可能なイニシャライザーがないため初期化できません。つまり、デフォルトの暗黙的なメンバーごとの初期化子にpublicキーワードを与えていません。

var collection1 = CollectionTO(index: 1, title: "New Releases", description: "All the new releases")

私は自分のinitメソッドを次のように追加する必要があります:

public struct CollectionTO {
    var index: Order
    var title: String
    var description: String

    public init(index: Order, title: String, description: String) {
        self.index = index;
        self.title = title;
        self.description = description;
    }

}

...しかし、誰かが知っている別の方法があれば私はむしろしたくないですか?

回答:


268

マニュアルの引用:

「構造体型のデフォルトのメンバーワイズ初期化子構造体タイプのデフォルトのメンバーワイズ初期化子は、構造体に保存されているプロパティのいずれかがプライベートの場合、プライベートと見なされます。それ以外の場合、初期化子のアクセスレベルは内部です。

上記のデフォルトのイニシャライザと同様に、別のモジュールで使用するときにメンバー構造のイニシャライザでパブリック構造体型を初期化できるようにする場合は、型の定義の一部としてパブリックメンバーワイズイニシャライザを自分で提供する必要があります。

「The Swift Programming Language」のセクション「Access Control」からの抜粋。


288
まあ、それは迷惑です。:(
Dan Loewenherz 2016年

7
[ github.com/apple/swift-evolution/blob/master/proposals/…言う:「クリス・ラトナーの引用:Swiftのデフォルトのメンバーごとの初期化子の動作には、少なくともこれらの欠陥(IMO)があります:2)アクセス制御+メンバーごとの初期化自分で実装する必要があります。」おそらくそれは、特に理由もなく存在する単なる欠陥です。これに関する参照はこれ以上見つかりませんでした。
Jano

8
@DanLoewenherzはい、それは不便です。根拠は次のとおりです。型メンバーをパブリックにしたい場合は、明示的にそのようにマークする必要があります。この要件により、タイプの公開APIがパブリッシュすることを選択したものであり、タイプの内部動作を誤ってパブリックAPIとして提示することが回避されます。」抜粋:Apple Inc.「The Swift Programming Language」iBooks。itun.es/gb/jEUH0.l
bandejapaisa

18
コンパイラディレクティブは、デフォルトの動作をオーバーライドして公開するのに適しています。
bandejapaisa 2017年

9
内部は、デフォルトのimoにとってひどい選択です。これは基本的に、初めてモジュールを外部から参照するときに予期しない問題が発生することを保証します。すべてをデフォルトでプライベートにしないで、適切なアクセスレベルが付与されていないことをすぐに確認し、それをパブリックにするか内部にするかを決定できますか?
devios1 2017

72

デフォルトのメンバーワイズ初期化子を持つことは不可能ですが、少なくとも次の手順ですばやく初期化できます。

  1. オブジェクトを構造体ではなく一時的にクラスにする
  2. 保存する
  3. クラス名を右クリックして、リファクタリング-> Memberwise Initializerの生成を選択します
  4. 構造体に戻します

鮮やかさ。この迅速な欠陥を回避するのに十分に感謝することができません
アントン・トロパシュコ

1
機能し、structsの代わりにクラスを実際に使用する動機付けyoutube.com/watch?v=_V2sBURgUBI
Isaac Carol Weisberg '20

それはスーパーチップです!!
ペイマンフ

6
Xcode 11以降では、構造体に対してメンバーワイズ初期化子を生成することもできます!
Brock Batsell

素晴らしい!!! それは正しい答えではありませんが、非常に良いヒントです!とても助かりました!
GuiOS


1

行ごとに完全なSwiftデータモデルファイルを解析し、パブリックアクセス修飾子、メンバーごとのデフォルトの初期化子などを個別の自動生成出力Swiftファイルに追加するためのRuby Gem haveができました。

この宝石はswift_republicと呼ばれています

このgemの実行については、次のドキュメントを確認してください:

https://github.com/mehul90/swift_republic


1
素晴らしいソリューション!! 私はすでにラッパーを作成し、swift_republic問題なく動作しています。
Md Shahed Hossain
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.