Swiftのアクセスレベル(private、fileprivate、internal、public、open)は、クラス、構造体およびそのプロパティだけでなく、ネストされた型にも影響します。ネストされた型は、特に明示的な制限が指定されていない場合、外部の型のアクセスレベルをデフォルトで継承します。
主なニュアンス:
internalとして宣言された場合、ネストされた型は外部よりもオープンになってはいけませんが、より「クローズド」にはなれます(例えば、外部がpublic、ネストされた型がprivateの場合)。internalとして宣言されたネストされた型は他のモジュールからは見えません。例:
public class A { public struct B { fileprivate func foo() {} } }
この例では、AとBはパブリックですが、メソッドfoo()はファイルプライベートです。
質問:「ネストされた型は、周囲の型よりも高いアクセスレベルを持つことができますか?」
回答: いいえ、ネストされた型のアクセスレベルは、周囲の型のアクセスレベルを超えることはできません。より高いアクセスレベルを持つネストされた型を宣言しようとすると、コンパイラはエラーを生成します。
エラー例:
internal struct MyStruct { public enum MyEnum { ... } // エラー:publicはinternalの内部に配置できません }
ストーリー 1
一般的なフレームワークでは、ネストされた構造体のアクセスレベルが外部の型と同期されていませんでした。リリース版で、クライアントアプリケーションで内部のenumを使用できない事態になり、インターフェースの緊急変更が必要でした。
ストーリー 2
大規模なプロジェクトで、内部サービスオブジェクトは、内部として宣言されたステータスを持つネストされたクラスを持っていました。このクラスに依存する新しいモジュールが登場した後、アクセスレベルを上げることなく統合することができず、SDKの完全な再コンパイルが必要になりました。
ストーリー 3
複雑なライブラリでは、一部のネストされた構造体がpublicとして宣言され、コンテナ自体はinternalでした。新しいバージョンへの移行中に、公開された型が外部コンテキストでコンパイルされず、複数のチームの更新が妨げられるという致命的なエラーが発生しました。