見出し画像

Swiftでプログラミング-Access Control

アクセス制御は、他のソースファイルやモジュールのコードからコードの一部へのアクセスを制限します。この機能を使用すると、コードの実装の詳細を非表示にし、そのコードにアクセスして使用できる優先インターフェイスを指定できます。

特定のアクセスレベルを個々の型(クラス、構造、列挙)、およびそれらの型に属するプロパティ、メソッド、イニシャライザー、および添え字に割り当てることができます。プロトコルは、グローバル定数、変数、および関数と同様に、特定のコンテキストに制限できます。

Swiftは、さまざまなレベルのアクセス制御を提供することに加えて、一般的な場面にはデフォルトのアクセスレベルを提供することにより、明示的なアクセス制御レベルを指定する必要性を減らします。実際、単一ターゲットアプリを作成している場合は、明示的なアクセス制御レベルを指定する必要がない場合があります。

アクセス制御を適用できるコードのさまざまな側面(プロパティ、タイプ、関数など)は、簡潔にするために、以下のセクションでは「エンティティ」と呼ばれます。

Modules and Source Files

Swiftのアクセス制御モデルは、モジュールとソースファイルの概念に基づいています。

モジュールは、コード配布の単一ユニットです。単一ユニットとして構築および使用され、Swiftのimportキーワードを使用して別のモジュールからインポートできるフレームワークまたはアプリケーションです。

Xcodeの各ビルドターゲット(アプリバンドルやフレームワークなど)は、Swiftでは個別のモジュールとして扱われます。 アプリのコードの側面を単独のフレームワークとしてグループ化すると(おそらく、そのコードを複数のアプリケーション間でカプセル化して再利用するため)、そのフレームワーク内で定義したものはすべて、アプリ内でインポートして使用するときに別のモジュールの一部になります。 または、別のフレームワーク内で使用される場合もあります。

ソースファイルは、モジュール内の単一のSwiftソースコードファイルです(実際には、アプリまたはフレームワーク内の単一のファイル)。 個別のソースファイルで個々のタイプを定義するのが一般的ですが、単一のソースファイルに複数のタイプや関数などの定義を含めることができます。

Access Levels

Swiftは、コード内のエンティティに5つの異なるアクセスレベルを提供します。これらのアクセスレベルは、エンティティが定義されているソースファイルに関連しており、ソースファイルが属するモジュールにも関連しています。

・オープンアクセスとパブリックアクセスにより、エンティティは、定義モジュールの任意のソースファイル内で使用できます。また、定義モジュールをインポートする別のモジュールのソースファイルでも使用できます。フレームワークへのパブリックインターフェイスを指定するときは、通常、オープンアクセスまたはパブリックアクセスを使用します。オープンアクセスとパブリックアクセスの違いを以下に説明します。
・内部アクセスにより、エンティティは定義モジュールの任意のソースファイル内で使用できますが、そのモジュール外のソースファイルでは使用できません。通常、アプリまたはフレームワークの内部構造を定義するときに内部アクセスを使用します。
・ファイルプライベートアクセスは、エンティティの使用を独自の定義ソースファイルに制限します。ファイルプライベートアクセスを使用して、特定の機能の実装の詳細がファイル全体で使用されている場合、それらの詳細を非表示にします。
・プライベートアクセスは、エンティティの使用を、囲んでいる宣言と、同じファイル内にあるその宣言の拡張子に制限します。プライベートアクセスを使用して、特定の機能の実装の詳細が単一の宣言内でのみ使用されている場合、それらの詳細を非表示にします。

オープンアクセスは最高(最も制限の少ない)アクセスレベルであり、プライベートアクセスは最低(最も制限の少ない)アクセスレベルです。

オープンアクセスはクラスとクラスメンバーにのみ適用され、以下のサブクラス化で説明するように、モジュール外のコードにサブクラス化とオーバーライドを許可するという点でパブリックアクセスとは異なります。クラスをオープンとしてマークすることは、そのクラスをスーパークラスとして使用する他のモジュールからのコードの影響を考慮し、それに応じてクラスのコードを設計したことを明示的に示します。

Guiding Principle of Access Levels

Swiftのアクセスレベルは、全体的な指針に従います。より低い(より制限的な)アクセスレベルを持つ別のエンティティに関してエンティティを定義することはできません。

例えば:

・パブリック変数は、内部、ファイルプライベート、またはプライベートタイプを持つものとして定義することはできません。これは、パブリック変数が使用されているすべての場所でタイプを使用できるとは限らないためです。
・関数は、その構成要素タイプが周囲のコードで使用できない状況で使用される可能性があるため、パラメータータイプおよび戻りタイプよりも高いアクセスレベルを持つことはできません。

言語のさまざまな側面に対するこの指導原則の具体的な意味については、以下で詳しく説明します。

Default Access Levels

明示的なアクセスレベルを自分で指定しない場合、コード内のすべてのエンティティ(この章で後述するいくつかの特定の例外を除く)には、デフォルトで内部のアクセスレベルを持ちます。 その結果、多くの場合、コードで明示的なアクセスレベルを指定する必要はありません。

Access Levels for Single-Target Apps

シンプルなシングルターゲットアプリを作成する場合、アプリ内のコードは通常、アプリ内に自己完結型であり、アプリのモジュールの外部で利用できるようにする必要はありません。 内部デフォルトのアクセスレベルは、すでにこの要件に一致しています。 したがって、カスタムアクセスレベルを指定する必要はありません。 ただし、アプリのモジュール内の他のコードから実装の詳細を隠すために、コードの一部をファイルプライベートまたはプライベートとしてマークすることをお勧めします。

Access Levels for Frameworks

フレームワークを開発するときは、そのフレームワークへの公開インターフェースをオープンまたはパブリックとしてマークして、フレームワークをインポートするアプリなどの他のモジュールから表示およびアクセスできるようにします。 この公開インターフェースは、フレームワークのアプリケーションプログラミングインターフェース(またはAPI)です。

フレームワークの内部実装の詳細は、引き続きデフォルトのアクセスレベルの内部を使用できます。または、フレームワークの内部コードの他の部分から非表示にする場合は、プライベートまたはファイルプライベートとしてマークすることができます。 フレームワークのAPIの一部にする場合にのみ、エンティティをオープンまたはパブリックとしてマークする必要があります。

Access Levels for Unit Test Targets

単体テストターゲットを使用してアプリを作成する場合、テストするには、アプリ内のコードをそのモジュールで利用できるようにする必要があります。 デフォルトでは、オープンまたはパブリックとしてマークされたエンティティのみが他のモジュールにアクセスできます。 ただし、@ testable属性を使用して製品モジュールのインポート宣言をマークし、テストを有効にしてその製品モジュールをコンパイルすると、単体テストターゲットは任意の内部エンティティにアクセスできます。

Access Control Syntax

エンティティの宣言の先頭にopen、public、internal、fileprivate、またはprivate修飾子のいずれかを配置して、エンティティのアクセスレベルを定義します。

   public class SomePublicClass {}
   internal class SomeInternalClass {}
   fileprivate class SomeFilePrivateClass {}
   private class SomePrivateClass {}
   public var somePublicVariable = 0
   internal let someInternalConstant = 0
   fileprivate func someFilePrivateFunction() {}
   private func somePrivateFunction() {}

特に指定がない限り、デフォルトのアクセスレベルで説明されているように、デフォルトのアクセスレベルは内部です。 これは、SomeInternalClassとsomeInternalConstantは、明示的なアクセスレベル修飾子なしで記述でき、引き続き内部のアクセスレベルを持つことを意味します。

class SomeInternalClass {}              // implicitly internal
let someInternalConstant = 0  

Custom Types

カスタム型に明示的なアクセスレベルを指定する場合は、タイプを定義する時点で指定します。新しいタイプは、アクセスレベルが許す限りどこでも使用できます。たとえば、file-privateクラスを定義する場合、そのクラスは、file-privateクラスが定義されているソースファイルで、プロパティの型として、または関数パラメーターまたは戻り型としてのみ使用できます。

型のアクセス制御レベルは、その型のメンバー(そのプロパティ、メソッド、イニシャライザー、および添え字)のデフォルトのアクセスレベルにも影響します。型のアクセスレベルをプライベートまたはファイルプライベートとして定義すると、そのメンバーのデフォルトのアクセスレベルもプライベートまたはファイルプライベートになります。タイプのアクセスレベルを内部またはパブリックとして定義する場合(またはアクセスレベルを明示的に指定せずに内部のデフォルトアクセスレベルを使用する場合)、タイプのメンバーのデフォルトアクセスレベルは内部になります。

パブリック型は、デフォルトでパブリックメンバーではなく内部メンバーを持つようになっています。タイプメンバーをパブリックにする場合は、明示的にそのようにマークする必要があります。この要件により、型の公開APIが公開を選択したものになり、型の内部動作が誤って公開APIとして表示されることが回避されます。
    public class SomePublicClass {                  // explicitly public class
       public var somePublicProperty = 0            // explicitly public class member
       var someInternalProperty = 0                 // implicitly internal class member
       fileprivate func someFilePrivateMethod() {}  // explicitly file-private class member
       private func somePrivateMethod() {}          // explicitly private class member
   }
   class SomeInternalClass {                       // implicitly internal class
       var someInternalProperty = 0                 // implicitly internal class member
       fileprivate func someFilePrivateMethod() {}  // explicitly file-private class member
       private func somePrivateMethod() {}          // explicitly private class member
   }
   fileprivate class SomeFilePrivateClass {        // explicitly file-private class
       func someFilePrivateMethod() {}              // implicitly file-private class member
       private func somePrivateMethod() {}          // explicitly private class member
   }
   private class SomePrivateClass {                // explicitly private class
       func somePrivateMethod() {}                  // implicitly private class member
   }

Tuple Types

タプル型のアクセスレベルは、そのタプルで使用されるすべての型の中で最も制限の厳しいアクセスレベルです。 たとえば、内部アクセスとプライベートアクセスの2つの異なるタイプからタプルを作成する場合、その複合タプルタイプのアクセスレベルはプライベートになります。

タプル型には、クラス、構造、列挙、関数のようにスタンドアロンの定義がありません。 タプルタイプのアクセスレベルは、タプルタイプを構成するタイプから自動的に決定され、明示的に指定することはできません。

Function Types

関数型のアクセスレベルは、関数のパラメータタイプと戻り型の中で最も制限の厳しいアクセスレベルとして計算されます。 関数の計算されたアクセスレベルが文脈と一致しない場合は、関数の定義の一部としてアクセスレベルを明示的に指定する必要があります。

以下の例では、関数自体に特定のアクセスレベル修飾子を指定せずに、someFunction()と呼ばれるグローバル関数を定義しています。 この関数のデフォルトのアクセスレベルは「内部」であると思われるかもしれませんが、そうではありません。 実際、someFunction()は以下のようにコンパイルされません。

    func someFunction() -> (SomeInternalClass, SomePrivateClass) {
       // function implementation goes here
   }

関数の戻り型は、上記のカスタム型で定義された2つのカスタムクラスから構成されるタプル型です。 これらのクラスの1つは内部として定義され、もう1つはプライベートとして定義されます。 したがって、複合タプルタイプの全体的なアクセスレベルはプライベートです(タプルの構成タイプの最小アクセスレベル)。

関数の戻り型はprivateであるため、関数宣言を有効にするには、関数の全体的なアクセスレベルをprivate修飾子でマークする必要があります。

    private func someFunction() -> (SomeInternalClass, SomePrivateClass) {
       // function implementation goes here
   }

関数のパブリックまたは内部ユーザーが関数の戻り型で使用されるプライベートクラスに適切にアクセスできない可能性があるため、someFunction()の定義をパブリックまたは内部修飾子でマークしたり、デフォルト設定の内部を使用したりすることは無効です。

Enumeration Types

列挙型の個々のケースは、それらが属する列挙型と同じアクセスレベルを自動的に受け取ります。 個々の列挙ケースに異なるアクセスレベルを指定することはできません。

以下の例では、CompassPoint列挙型の明示的なアクセスレベルはpublicです。 したがって、北、南、東、および西の列挙ケースには、パブリックのアクセスレベルもあります。

    public enum CompassPoint {
       case north
       case south
       case east
       case west
   }

Raw Values and Associated Values

列挙型定義の生の値または関連する値に使用される型には、少なくとも列挙型のアクセスレベルと同じ高さのアクセスレベルが必要です。 たとえば、内部アクセスレベルを持つ列挙型の生の値型としてプライベート型を使用することはできません。

Nested Types

ネストされた型のアクセスレベルは、含まれている型がパブリックでない限り、含まれている型と同じです。 パブリック型内で定義されたネストされた型には、内部の自動アクセスレベルがあります。 パブリック型内のネストされた型をパブリックに使用できるようにする場合は、ネストされた型をパブリックとして明示的に宣言する必要があります。

Subclassing

現在のアクセスコンテキストでアクセスでき、サブクラスと同じモジュールで定義されている任意のクラスをサブクラス化できます。別のモジュールで定義されているオープンクラスをサブクラス化することもできます。サブクラスは、そのスーパークラスよりも高いアクセスレベルを持つことはできません。たとえば、内部スーパークラスのパブリックサブクラスを作成することはできません。

さらに、同じモジュールで定義されているクラスの場合、特定のアクセスコンテキストで表示される任意のクラスメンバー(メソッド、プロパティ、初期化子、または添え字)をオーバーライドできます。別のモジュールで定義されているクラスの場合、開いているクラスメンバーをオーバーライドできます。

オーバーライドにより、継承されたクラスメンバーがそのスーパークラスバージョンよりもアクセスしやすくなります。以下の例では、クラスAはsomeMethod()と呼ばれるファイルプライベートメソッドを持つパブリッククラスです。クラスBはAのサブクラスであり、アクセスレベルは「内部」に制限されています。それにもかかわらず、クラスBは、someMethod()の元の実装よりも高い「内部」のアクセスレベルでsomeMethod()のオーバーライドを提供します。

    public class A {
       fileprivate func someMethod() {}
   }
   internal class B: A {
       override internal func someMethod() {}
   }

スーパークラスのメンバーへの呼び出しが許可されたアクセスレベルのコンテキスト内(つまり、 ファイルプライベートメンバー呼び出しのスーパークラス、または内部メンバー呼び出しのスーパークラスと同じモジュール内):

   public class A {
       fileprivate func someMethod() {}
   }
   internal class B: A {
       override internal func someMethod() {
           super.someMethod()
       }
   }

スーパークラスAとサブクラスBは同じソースファイルで定義されているため、someMethod()のB実装がsuper.someMethod()を呼び出すことは有効です。

Constants, Variables, Properties, and Subscripts

定数、変数、またはプロパティは、そのタイプよりも公開することはできません。 たとえば、プライベートタイプでパブリックプロパティを作成することは無効です。 同様に、添え字は、そのインデックスタイプまたはリターンタイプよりも公開することはできません。

定数、変数、プロパティ、または添え字がプライベートタイプを使用する場合、定数、変数、プロパティ、または添え字もプライベートとしてマークする必要があります。

private var privateInstance = SomePrivateClass()

Getters and Setters

定数、変数、プロパティ、および添え字のゲッターとセッターは、それらが属する定数、変数、プロパティ、または添え字と同じアクセスレベルを自動的に受け取ります。

セッターに対応するゲッターよりも低いアクセスレベルを指定して、その変数、プロパティ、または添え字の読み取り/書き込みスコープを制限できます。 varまたは添え字のイントロデューサの前にfileprivate(set)、private(set)、またはinternal(set)を書き込むことにより、より低いアクセスレベルを割り当てます。

このルールは、保存されたプロパティと計算されたプロパティに適用されます。保存されたプロパティの明示的なゲッターとセッターを記述しなくても、Swiftは、保存されたプロパティのバッキングストレージへのアクセスを提供するために、暗黙的なゲッターとセッターを合成します。 fileprivate(set)、private(set)、およびinternal(set)を使用して、計算されたプロパティの明示的なセッターの場合とまったく同じ方法で、この合成されたセッターのアクセスレベルを変更します。

以下の例では、文字列プロパティが変更された回数を追跡するTrackedStringという構造を定義しています。

    struct TrackedString {
       private(set) var numberOfEdits = 0
       var value: String = "" {
           didSet {
               numberOfEdits += 1
           }
       }
   }

TrackedString構造体は、valueと呼ばれる格納された文字列プロパティを定義します。初期値は ""(空の文字列)です。この構造体は、numberOfEditsと呼ばれる格納された整数プロパティも定義します。これは、その値が変更された回数を追跡するために使用されます。この変更の追跡は、valueプロパティのdidSetプロパティオブザーバーを使用して実装されます。このオブザーバーは、valueプロパティが新しい値に設定されるたびにnumberOfEditsをインクリメントします。

TrackedString構造体とvalueプロパティは、明示的なアクセスレベル修飾子を提供しないため、どちらもデフォルトの内部アクセスレベルを受け取ります。ただし、numberOfEditsプロパティのアクセスレベルはprivate(set)修飾子でマークされ、プロパティのゲッターが引き続き内部のデフォルトのアクセスレベルを持っていることを示しますが、プロパティはTrackedString構造の一部であるコード内からのみ設定可能です。これにより、TrackedStringはnumberOfEditsプロパティを内部的に変更できますが、構造体の定義外で使用される場合は、プロパティを読み取り専用プロパティとして表示できます。

TrackedStringインスタンスを作成し、その文字列値を数回変更すると、変更の数に一致するようにnumberOfEditsプロパティ値が更新されることがわかります。

   var stringToEdit = TrackedString()
   stringToEdit.value = "This string will be tracked."
   stringToEdit.value += " This edit will increment numberOfEdits."
   stringToEdit.value += " So will this one."
   print("The number of edits is \(stringToEdit.numberOfEdits)")
   // Prints "The number of edits is 3"

別のソースファイル内からnumberOfEditsプロパティの現在の値をクエリすることはできますが、別のソースファイルからプロパティを変更することはできません。 この制限は、TrackedString編集追跡機能の実装の詳細を保護すると同時に、その機能の側面への便利なアクセスを提供します。

必要に応じて、ゲッターとセッターの両方に明示的なアクセスレベルを割り当てることができることに注意してください。 以下の例は、構造がpublicの明示的なアクセスレベルで定義されているTrackedString構造のバージョンを示しています。 したがって、構造体のメンバー(numberOfEditsプロパティを含む)には、デフォルトで内部アクセスレベルがあります。 publicとprivate(set)のアクセスレベル修飾子を組み合わせることで、構造体のnumberOfEditsプロパティgetterをpublicにし、そのプロパティsetterをprivateにすることができます。

    public struct TrackedString {
       public private(set) var numberOfEdits = 0
       public var value: String = "" {
           didSet {
               numberOfEdits += 1
           }
       }
       public init() {}
   }

Initializers

カスタムイニシャライザには、初期化する型以下のアクセスレベルを割り当てることができます。 唯一の例外は、必要なイニシャライザー(必須のイニシャライザーで定義されている)の場合です。 必要なイニシャライザーは、それが属するクラスと同じアクセスレベルを持っている必要があります。

関数およびメソッドのパラメーターと同様に、イニシャライザーのパラメーターの型は、イニシャライザー自体のアクセスレベルよりもプライベートにすることはできません。

Default Initializers

デフォルトのイニシャライザーで説明されているように、Swiftは、すべてのプロパティのデフォルト値を提供し、少なくとも1つのイニシャライザー自体を提供しない構造体または基本クラスの引数なしで、デフォルトのイニシャライザーを自動的に提供します。

デフォルトのイニシャライザーは、その型がパブリックとして定義されていない限り、初期化する型と同じアクセスレベルを持ちます。 publicとして定義されている型の場合、デフォルトのイニシャライザは内部と見なされます。 別のモジュールで使用するときにパブリック型を引数なしのイニシャライザーで初期化できるようにする場合は、型の定義の一部として、引数なしのパブリック型イニシャライザーを自分で明示的に指定する必要があります。

Default Memberwise Initializers for Structure Types

構造体に格納されているプロパティのいずれかがプライベートである場合、構造体タイプのデフォルトのメンバーごとの初期化子はプライベートと見なされます。 同様に、構造体に格納されているプロパティのいずれかがファイルプライベートである場合、イニシャライザはファイルプライベートです。 それ以外の場合、イニシャライザのアクセスレベルは内部です。

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

Protocols

プロトコルタイプに明示的なアクセスレベルを割り当てる場合は、プロトコルを定義する時点で割り当てます。 これにより、特定のアクセスコンテキスト内でのみ採用できるプロトコルを作成できます。

プロトコル定義内の各要件のアクセスレベルは、プロトコルと同じアクセスレベルに自動的に設定されます。 プロトコル要件を、サポートされているプロトコルとは異なるアクセスレベルに設定することはできません。 これにより、プロトコルを採用するすべてのタイプで、プロトコルのすべての要件が確実に表示されます。

パブリックプロトコルを定義する場合、プロトコルの要件は、それらが実装されるときにそれらの要件のパブリックアクセスレベルを必要とします。 この動作は、パブリック型の定義が型のメンバーの内部のアクセスレベルを意味する他の型とは異なります。

Protocol Inheritance

既存のプロトコルから継承する新しいプロトコルを定義する場合、新しいプロトコルは、継承元のプロトコルと最大で同じアクセスレベルを持つことができます。 たとえば、内部プロトコルを継承するパブリックプロトコルを作成することはできません。

Protocol Conformance

型は、型自体よりもアクセスレベルが低いプロトコルに準拠できます。たとえば、他のモジュールで使用できるパブリック型を定義できますが、内部プロトコルへの準拠は、内部プロトコルの定義モジュール内でのみ使用できます。

タイプが特定のプロトコルに準拠するコンテキストは、タイプのアクセスレベルとプロトコルのアクセスレベルの最小値です。たとえば、型がパブリックであるが、それが準拠するプロトコルが内部である場合、そのプロトコルへの型の準拠も内部です。

プロトコルに準拠するように型を記述または拡張する場合、各プロトコル要件の型の実装が、そのプロトコルへの型の準拠と少なくとも同じアクセスレベルを持っていることを確認する必要があります。たとえば、パブリックタイプが内部プロトコルに準拠している場合、各プロトコル要件のタイプの実装は少なくとも内部である必要があります。

Swiftでは、Objective-Cと同様に、プロトコルへの準拠はグローバルです。同じプログラム内で2つの異なる方法で型がプロトコルに準拠することはできません。

Extensions

クラス、構造、または列挙が使用可能な任意のアクセスコンテキストで、クラス、構造、または列挙を拡張できます。拡張機能に追加された型メンバーは、拡張される元の型で宣言された型メンバーと同じデフォルトのアクセスレベルを持ちます。public型またはinternal型を拡張する場合、追加する新しい型メンバーのデフォルトのアクセスレベルはinternalです。 file-privateタイプを拡張する場合、追加する新しいタイプのメンバーには、ファイルprivateのデフォルトのアクセスレベルがあります。private型を拡張する場合、追加する新しい型のメンバーには、デフォルトのアクセスレベルがprivateになります。

または、extensionに明示的なアクセスレベル修飾子(たとえば、private)を付けて、extension内で定義されたすべてのメンバーに新しいデフォルトのアクセスレベルを設定することもできます。この新しいデフォルトは、個々の型メンバーのextension内で引き続きオーバーライドできます。

extensionを使用してプロトコル準拠を追加している場合、extensionに明示的なアクセスレベル修飾子を指定することはできません。代わりに、プロトコル自体のアクセスレベルを使用して、extension内の各プロトコル要件の実装にデフォルトのアクセスレベルを提供します。

Private Members in Extensions

拡張するクラス、構造、または列挙と同じファイル内にあるextensionは、extension内のコードが元の型の宣言の一部として記述されているかのように動作します。 その結果、次のことが可能になります。

元の宣言でprivateメンバーを宣言し、同じファイルの拡張子からそのメンバーにアクセスします。
ある拡張子でprivateメンバーを宣言し、同じファイル内の別の拡張子からそのメンバーにアクセスします。
extensionでprivateメンバーを宣言し、同じファイルの元の宣言からそのメンバーにアクセスします。

この動作は、型にprivateエンティティがあるかどうかに関係なく、同じ方法でextensionを使用してコードを整理できることを意味します。 たとえば、次の単純なプロトコルがあるとします。

   protocol SomeProtocol {
       func doSomething()
   }

次のように、extensionを使用してプロトコル適合性を追加できます。

   struct SomeStruct {
       private var privateVariable = 12
   }
   extension SomeStruct: SomeProtocol {
       func doSomething() {
           print(privateVariable)
       }
   }

Generics

ジェネリック型またはジェネリック関数のアクセスレベルは、ジェネリック型または関数自体のアクセスレベルと、その型パラメーターに対する型制約のアクセスレベルの最小値です。

Type Aliases

定義したタイプエイリアスは、アクセス制御の目的で個別の型として扱われます。 タイプエイリアスは、エイリアスするタイプのアクセスレベル以下のアクセスレベルを持つことができます。 たとえば、private型のエイリアスは、private、file-private、internal、public、またはopen型のエイリアスを作成できますが、public型のエイリアスは、internal、フfile-private、またはプprivate型のエイリアスを作成できません。

このルールは、プロトコルの適合性を満たすために使用される関連型の型エイリアスにも適用されます。

この記事が気に入ったらサポートをしてみませんか?