アクセスコントロール
Swiftでコードの可視性を宣言、ファイル、モジュールで管理します。
概要
アクセス制御は、他のソースファイルやモジュールのコードからコードの一部へのアクセスを制限します。この機能によってコードの実装の詳細を隠し、そのコードにアクセスして使用できる優先的なインターフェースを指定できます。
個々の型(クラス、構造体、列挙型)や、それらの型に属するプロパティ、メソッド、イニシャライザ、サブスクリプトに特定のアクセスレベルを割り当てることができます。プロトコルは特定のコンテキストに制限することができ、グローバル定数、変数、関数も同様です。
Note
以下のセクションでは、簡潔にするために、アクセス制御を適用できるコードのさまざまな側面(プロパティ、型、関数など)を「エンティティ」と呼びます。
モジュール、ソースファイル、パッケージ
Swiftのアクセス制御モデルは、モジュール、ソースファイル、パッケージの概念に基づいています。
モジュール
モジュールは、コード配布の単一単位です - 単一のユニットとしてビルドおよび出荷され、Swiftのimport
キーワードで別のモジュールによってインポートできるフレームワークまたはアプリケーションです。
ソースファイル
ソースファイルは、モジュール内の単一のSwiftソースコードファイルです(実質的には、アプリまたはフレームワーク内の単一ファイル)。個々の型を別々のソースファイルに定義することが一般的ですが、単一のソースファイルに複数の型、関数などの定義を含めることができます。
パッケージ
パッケージは、単一のユニットとして開発するモジュールのグループです。パッケージを構成するモジュールは、Swiftソースコードの一部としてではなく、使用しているビルドシステムの設定の一部として定義します。たとえば、Swift Package Managerを使用してコードをビルドする場合、Package.swiftファイルでPackageDescriptionモジュールのAPIを使用してパッケージを定義します。Xcodeを使用する場合、Package Access Identifierビルド設定でパッケージ名を指定します。
アクセスレベル
Swiftは、コード内のエンティティに対して6つの異なるアクセスレベルを提供します。これらのアクセスレベルは、エンティティが定義されているソースファイル、そのソースファイルが属するモジュール、およびそのモジュールが属するパッケージに対して相対的です。
open
アクセスとpublic
アクセスは、定義モジュールの任意のソースファイル内、および定義モジュールをインポートする別のモジュールのソースファイル内でエンティティを使用できるようにします。通常、フレームワークの公開インターフェースを指定する際にopen
またはpublic
アクセスを使用します。open
アクセスとpublic
アクセスの違いは、後述のサブクラス化で説明します。package
アクセスは、定義パッケージの任意のソースファイル内でエンティティを使用できるようにしますが、そのパッケージ外のソースファイルでは使用できません。通常、複数のモジュールに構造化されたアプリやフレームワーク内でpackage
アクセスを使用します。internal
アクセスは、定義モジュールの任意のソースファイル内でエンティティを使用できるようにしますが、そのモジュール外のソースファイルでは使用できません。通常、アプリやフレームワークの内部構造を定義する際にinternal
アクセスを使用します。file-private
アクセスは、エンティティの使用を定義ソースファイル内に制限します。特定の機能の実装の詳細を隠すためにfile-private
アクセスを使用します。private
アクセスは、エンティティの使用を囲む宣言および同じファイル内のその宣言の拡張に制限します。特定の機能の実装の詳細を隠すためにprivate
アクセスを使用します。
open
アクセスは最も高い(最も制限の少ない)アクセスレベルであり、private
アクセスは最も低い(最も制限の多い)アクセスレベルです。
open
アクセスはクラスおよびクラスメンバーにのみ適用され、モジュール外のコードがサブクラス化およびオーバーライドできる点でpublic
アクセスとは異なります。クラスをopen
としてマークすることは、他のモジュールのコードがそのクラスをスーパークラスとして使用する影響を考慮し、そのクラスのコードを適切に設計したことを明示的に示します。
アクセスレベルの指針
Swiftのアクセスレベルは、全体的な指針に従います: あるエンティティは、より低い(より制限の多い)アクセスレベルを持つ別のエンティティに基づいて定義することはできません。
たとえば:
public
変数は、internal
、file-private
、またはprivate
型を持つように定義することはできません。なぜなら、その型はpublic
変数が使用されるすべての場所で利用可能であるとは限らないからです。- 関数は、そのパラメータ型および戻り型よりも高いアクセスレベルを持つことはできません。なぜなら、その関数は、その構成要素の型が周囲のコードで利用できない状況で使用される可能性があるからです。
この指針の具体的な意味は、言語のさまざまな側面に対して以下で詳しく説明します。
デフォルトのアクセスレベル
コード内のすべてのエンティティ(この章で後述するいくつかの特定の例外を除く)は、明示的なアクセスレベルを指定しない場合、デフォルトのアクセスレベルとしてinternal
を持ちます。そのため、多くの場合、コード内で明示的なアクセスレベルを指定する必要はありません。
シングルターゲットアプリのアクセスレベル
シンプルなシングルターゲットアプリを書くとき、アプリ内のコードは通常、アプリ内で自己完結しており、アプリのモジュール外で利用可能にする必要はありません。デフォルトのアクセスレベルであるinternal
は、この要件にすでに一致しています。したがって、カスタムアクセスレベルを指定する必要はありません。ただし、アプリのモジュール内の他のコードから実装の詳細を隠すために、コードの一部をfile-private
またはprivate
としてマークすることはできます。
フレームワークのアクセスレベル
フレームワークを開発する際には、そのフレームワークの公開インターフェースをopen
またはpublic
としてマークし、他のモジュール(フレームワークをインポートするアプリなど)から表示およびアクセスできるようにします。この公開インターフェースは、フレームワークのアプリケーションプログラミングインターフェース(API)です。
Note
フレームワークの内部実装の詳細は、デフォルトのアクセスレベルであるinternal
を使用するか、他のフレームワークの内部コードから隠すためにprivate
またはfile-private
としてマークできます。エンティティをopen
またはpublic
としてマークする必要があるのは、そのエンティティをフレームワークのAPIの一部にしたい場合だけです。
ユニットテストターゲットのアクセスレベル
ユニットテストターゲットを持つアプリを書くとき、アプリ内のコードはそのモジュールに対して利用可能にする必要があります。デフォルトでは、open
またはpublic
としてマークされたエンティティのみが他のモジュールからアクセス可能です。ただし、ユニットテストターゲットは、製品モジュールのインポート宣言に@testable
属性をマークし、その製品モジュールをテスト有効でコンパイルすることで、任意のinternal
エンティティにアクセスできます。
アクセス制御の構文
エンティティの宣言の先頭にopen
、public
、internal
、fileprivate
、またはprivate
修飾子を配置して、エンティティのアクセスレベルを定義します。
open class SomeOpenClass {}
public class SomePublicClass {}
internal class SomeInternalClass {}
fileprivate class SomeFilePrivateClass {}
private class SomePrivateClass {}
open var someOpenVariable = 0
public var somePublicVariable = 0
internal let someInternalConstant = 0
fileprivate func someFilePrivateFunction() {}
private func somePrivateFunction() {}
明示的に指定されていない場合、デフォルトのアクセスレベルはinternal
です。これは、SomeInternalClass
およびsomeInternalConstant
が明示的なアクセスレベル修飾子なしで書かれても、アクセスレベルがinternal
であることを意味します。
class SomeInternalClass {} // 暗黙的にinternal
let someInternalConstant = 0 // 暗黙的にinternal
カスタム型
カスタム型の明示的なアクセスレベルを指定する場合は、その型を定義する時点で行います。新しい型は、そのアクセスレベルが許す限り、どこでも使用できます。たとえば、ファイルプライベートクラスを定義する場合、そのクラスはファイルプライベートクラスが定義されているソースファイル内でのみ、プロパティの型、関数のパラメータ、または戻り型として使用できます。
型のアクセス制御レベルは、その型のメンバー(プロパティ、メソッド、イニシャライザ、サブスクリプト)のデフォルトのアクセスレベルにも影響します。型のアクセスレベルをprivate
またはfile-private
として定義すると、そのメンバーのデフォルトのアクセスレベルもprivate
またはfile-private
になります。型のアクセスレベルをinternal
またはpublic
として定義する(または明示的にアクセスレベルを指定せずにデフォルトのアクセスレベルであるinternal
を使用する)場合、その型のメンバーのデフォルトのアクセスレベルはinternal
になります。
Important
public
型はデフォルトでinternal
メンバーを持ちます。public
メンバーにしたい場合は、明示的にマークする必要があります。この要件は、型の公開APIが公開することを選択したものであり、型の内部動作を誤って公開APIとして提示することを避けるためです。
public class SomePublicClass { // 明示的にpublicクラス
public var somePublicProperty = 0 // 明示的にpublicクラスメンバー
var someInternalProperty = 0 // 暗黙的にinternalクラスメンバー
fileprivate func someFilePrivateMethod() {} // 明示的にfile-privateクラスメンバー
private func somePrivateMethod() {} // 明示的にprivateクラスメンバー
}
class SomeInternalClass { // 暗黙的にinternalクラス
var someInternalProperty = 0 // 暗黙的にinternalクラスメンバー
fileprivate func someFilePrivateMethod() {} // 明示的にfile-privateクラスメンバー
private func somePrivateMethod() {} // 明示的にprivateクラスメンバー
}
fileprivate class SomeFilePrivateClass { // 明示的にfile-privateクラス
func someFilePrivateMethod() {} // 暗黙的にfile-privateクラスメンバー
private func somePrivateMethod() {} // 明示的にprivateクラスメンバー
}
private class SomePrivateClass { // 明示的にprivateクラス
func somePrivateMethod() {} // 暗黙的にprivateクラスメンバー
}
タプル型
タプル型のアクセスレベルは、そのタプルに使用されるすべての型の中で最も制限の厳しいアクセスレベルです。たとえば、internal
アクセスとprivate
アクセスの2つの異なる型からタプルを構成する場合、その複合タプル型のアクセスレベルはprivate
になります。
Note
タプル型は、クラス、構造体、列挙型、関数のように独立した定義を持ちません。タプル型のアクセスレベルは、タプル型を構成する型から自動的に決定され、明示的に指定することはできません。
関数型
関数型のアクセスレベルは、関数のパラメータ型および戻り型の中で最も制限の厳しいアクセスレベルとして計算されます。関数の計算されたアクセスレベルがコンテキストのデフォルトと一致しない場合は、関数の定義の一部としてアクセスレベルを明示的に指定する必要があります。
以下の例では、特定のアクセスレベル修飾子を提供せずに、someFunction()
というグローバル関数を定義しています。この関数はデフォルトのアクセスレベルであるinternal
を持つと予想されるかもしれませんが、実際にはそうではありません。以下のように書かれたsomeFunction()
はコンパイルされません。
func someFunction() -> (SomeInternalClass, SomePrivateClass) {
// 関数の実装がここに入ります
}
関数の戻り型は、上記のカスタム型で定義された2つのクラスから構成されるタプル型です。これらのクラスの1つはinternal
として定義され、もう1つはprivate
として定義されています。したがって、複合タプル型の全体的なアクセスレベルはprivate
です(タプルの構成要素の最小アクセスレベル)。
関数の戻り型がprivate
であるため、関数宣言が有効であるためには、関数全体のアクセスレベルをprivate
修飾子でマークする必要があります。
private func someFunction() -> (SomeInternalClass, SomePrivateClass) {
// 関数の実装がここに入ります
}
someFunction()
の定義をpublic
またはinternal
修飾子でマークすることや、デフォルトの設定であるinternal
を使用することは有効ではありません。なぜなら、関数のpublic
またはinternal
ユーザーが、関数の戻り型で使用されるprivate
クラスに適切にアクセスできない可能性があるからです。
列挙型
列挙型の個々のケースは、自動的にそれが属する列挙型と同じアクセスレベルを受け取ります。個々の列挙型ケースに対して異なるアクセスレベルを指定することはできません。
以下の例では、CompassPoint
列挙型は明示的なアクセスレベルとしてpublic
を持っています。したがって、列挙型ケースnorth
、south
、east
、west
もpublic
アクセスレベルを持ちます。
public enum CompassPoint {
case north
case south
case east
case west
}
生の値と関連値
列挙型定義の生の値や関連値に使用される型は、列挙型のアクセスレベルと同じかそれ以上のアクセスレベルを持つ必要があります。たとえば、internal
アクセスレベルの列挙型の生の値の型としてprivate
型を使用することはできません。
ネスト型
ネスト型のアクセスレベルは、その包含型と同じです。ただし、包含型がpublic
でない限り、ネスト型は自動的にinternal
アクセスレベルを持ちます。public
型内のネスト型を公開したい場合は、そのネスト型を明示的にpublic
として宣言する必要があります。
サブクラス化
現在のアクセスコンテキストでアクセスできるクラスで、サブクラス化できるクラスは、サブクラスと同じモジュール内で定義されているクラスです。また、別のモジュールで定義されたopen
クラスもサブクラス化できます。サブクラスは、そのスーパークラスよりも高いアクセスレベルを持つことはできません。たとえば、internal
スーパークラスのpublic
サブクラスを書くことはできません。
さらに、同じモジュール内で定義されたクラスの場合、特定のアクセスコンテキストで表示される任意のクラスメンバー(メソッド、プロパティ、イニシャライザ、サブスクリプト)をオーバーライドできます。別のモジュールで定義されたクラスの場合、任意のopen
クラスメンバーをオーバーライドできます。
オーバーライドは、スーパークラスのバージョンよりもアクセス可能な継承クラスメンバーを作成できます。以下の例では、クラスA
はfile-private
メソッドsomeMethod()
を持つpublic
クラスです。クラスB
は、アクセスレベルがinternal
に減少したA
のサブクラスです。それにもかかわらず、クラスB
は、アクセスレベルがinternal
であるsomeMethod()
のオーバーライドを提供します。これは、someMethod()
の元の実装よりも高いアクセスレベルです。
public class A {
fileprivate func someMethod() {}
}
internal class B: A {
override internal func someMethod() {}
}
サブクラスメンバーが、スーパークラスメンバーよりも低いアクセス許可を持つスーパークラスメンバーを呼び出すことも有効です。スーパークラスメンバーの呼び出しが許可されたアクセスレベルコンテキスト内(つまり、file-private
メンバー呼び出しの場合はスーパークラスと同じソースファイル内、internal
メンバー呼び出しの場合はスーパークラスと同じモジュール内)で行われる限りです。
public class A {
fileprivate func someMethod() {}
}
internal class B: A {
override internal func someMethod() {
super.someMethod()
}
}
スーパークラスA
とサブクラスB
が同じソースファイル内で定義されているため、B
のsomeMethod()
の実装がsuper.someMethod()
を呼び出すことは有効です。
定数、変数、プロパティ、サブスクリプト
定数、変数、プロパティは、その型よりも公開されることはできません。たとえば、private
型のpublic
プロパティを書くことは有効ではありません。同様に、サブスクリプトは、そのインデックス型または戻り型よりも公開されることはできません。
定数、変数、プロパティ、サブスクリプトがprivate
型を使用する場合、その定数、変数、プロパティ、サブスクリプトもprivate
としてマークする必要があります。
private var privateInstance = SomePrivateClass()
ゲッターとセッター
定数、変数、プロパティ、サブスクリプトのゲッターとセッターは、自動的にそれらが属する定数、変数、プロパティ、サブスクリプトと同じアクセスレベルを受け取ります。
セッターに対応するゲッターよりも低いアクセスレベルを与えて、その変数、プロパティ、サブスクリプトの読み書き範囲を制限できます。var
またはサブスクリプトの導入子の前にfileprivate(set)
、private(set)
、internal(set)
、package(set)
を書いて、低いアクセスレベルを割り当てます。
Note
このルールは、格納プロパティと計算プロパティの両方に適用されます。格納プロパティに対して明示的なゲッターとセッターを書かない場合でも、Swiftは格納プロパティのバックストレージにアクセスするための暗黙的なゲッターとセッターを合成します。fileprivate(set)
、private(set)
、internal(set)
、package(set)
を使用して、計算プロパティの明示的なセッターと同じ方法で、この合成されたセッターのアクセスレベルを変更します。
以下の例では、TrackedString
という構造体を定義し、文字列プロパティが変更された回数を追跡します。
struct TrackedString {
private(set) var numberOfEdits = 0
var value: String = "" {
didSet {
numberOfEdits += 1
}
}
}
TrackedString
構造体は、value
という名前の格納文字列プロパティを定義し、初期値として""
(空の文字列)を持ちます。この構造体は、numberOfEdits
という名前の格納整数プロパティも定義し、value
が変更されるたびにその回数を追跡します。この変更追跡は、value
プロパティのdidSet
プロパティオブザーバを使用して実装されており、value
プロパティが新しい値に設定されるたびにnumberOfEdits
をインクリメントします。
TrackedString
構造体とvalue
プロパティは、明示的なアクセスレベル修飾子を提供していないため、デフォルトのアクセスレベルであるinternal
を受け取ります。ただし、numberOfEdits
プロパティのアクセスレベルはprivate(set)
修飾子でマークされており、プロパティのゲッターはデフォルトのアクセスレベルであるinternal
を持ちますが、プロパティは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
の編集追跡機能の実装の詳細が保護されますが、その機能の一部に便利にアクセスできます。
ゲッターとセッターの両方に明示的なアクセスレベルを割り当てることもできます。以下の例では、TrackedString
構造体のバージョンを示しており、構造体は明示的なアクセスレベルとしてpublic
を持っています。したがって、構造体のメンバー( numberOfEdits
プロパティを含む)はデフォルトでinternal
アクセスレベルを持ちます。numberOfEdits
プロパティのゲッターをpublic
にし、プロパティのセッターをprivate
にするには、public
およびprivate(set)
アクセスレベル修飾子を組み合わせます。
public struct TrackedString {
public private(set) var numberOfEdits = 0
public var value: String = "" {
didSet {
numberOfEdits += 1
}
}
public init() {}
}
イニシャライザ
カスタムイニシャライザには、初期化する型と同じかそれ以下のアクセスレベルを割り当てることができます。唯一の例外は、必須イニシャライザ(Required Initializers)です。必須イニシャライザは、そのクラスと同じアクセスレベルを持つ必要があります。
関数およびメソッドのパラメータと同様に、イニシャライザのパラメータの型は、イニシャライザ自体のアクセスレベルよりも非公開にすることはできません。
デフォルトイニシャライザ
デフォルトイニシャライザで説明されているように、Swiftは、すべてのプロパティにデフォルト値を提供し、少なくとも1つのイニシャライザを提供しない構造体または基本クラスに対して、引数なしのデフォルトイニシャライザを自動的に提供します。
デフォルトイニシャライザは、その型が初期化する型と同じアクセスレベルを持ちます。ただし、その型がpublic
として定義されている場合を除きます。public
として定義された型の場合、デフォルトイニシャライザはinternal
と見なされます。別のモジュールで使用する場合に引数なしのイニシャライザで初期化可能なpublic
型にしたい場合は、その型の定義の一部として明示的にpublic
引数なしのイニシャライザを提供する必要があります。
構造体型のデフォルトメンバワイズイニシャライザ
構造体型のデフォルトメンバワイズイニシャライザは、構造体の格納プロパティのいずれかがprivate
である場合、private
と見なされます。同様に、構造体の格納プロパティのいずれかがfile-private
である場合、イニシャライザはfile-private
と見なされます。それ以外の場合、イニシャライザはinternal
アクセスレベルを持ちます。
上記のデフォルトイニシャライザと同様に、別のモジュールで使用する場合にメンバワイズイニシャライザで初期化可能なpublic
構造体型にしたい場合は、その型の定義の一部として明示的にpublic
メンバワイズイニシャライザを提供する必要があります。
プロトコル
プロトコル型に明示的なアクセスレベルを割り当てたい場合は、そのプロトコルを定義する時点で行います。これにより、特定のアクセスコンテキスト内でのみ採用できるプロトコルを作成できます。
プロトコル定義内の各要件のアクセスレベルは、自動的にプロトコルと同じアクセスレベルに設定されます。プロトコルをサポートするプロトコル要件に対して異なるアクセスレベルを設定することはできません。これにより、プロトコルを採用する任意の型でプロトコルのすべての要件が表示されることが保証されます。
Note
public
プロトコルを定義する場合、プロトコルの要件は実装時にそれらの要件に対してpublic
アクセスレベルを必要とします。この動作は、public
型定義がその型のメンバーに対してinternal
アクセスレベルを暗示する他の型とは異なります。
プロトコルの継承
既存のプロトコルから継承する新しいプロトコルを定義する場合、新しいプロトコルは継承するプロトコルと同じアクセスレベルを持つことができます。たとえば、internal
プロトコルから継承するpublic
プロトコルを書くことはできません。
プロトコルの準拠
型は、型自体よりも低いアクセスレベルのプロトコルに準拠できます。たとえば、他のモジュールで使用できるpublic
型を定義できますが、その準拠は内部プロトコルの定義モジュール内でのみ使用できます。
型が特定のプロトコルに準拠するコンテキストは、型のアクセスレベルとプロトコルのアクセスレベルの最小値です。たとえば、型がpublic
であり、準拠するプロトコルがinternal
である場合、その型のプロトコル準拠もinternal
です。
型をプロトコルに準拠させるか、プロトコルに準拠するように型を拡張する場合、プロトコル準拠に対する型の実装が、そのプロトコル準拠のアクセスレベルと同じかそれ以上のアクセスレベルを持つことを確認する必要があります。たとえば、public
型がinternal
プロトコルに準拠する場合、その型の各プロトコル要件の実装は少なくともinternal
である必要があります。
Note
Swiftでは、Objective-Cと同様に、プロトコル準拠はグローバルです。プログラム内で同じ型が2つの異なる方法でプロトコルに準拠することはできません。
拡張
クラス、構造体、列挙型を、そのクラス、構造体、列挙型が利用可能な任意のアクセスコンテキストで拡張できます。拡張に追加された型メンバーは、拡張される元の型で宣言された型メンバーと同じデフォルトのアクセスレベルを持ちます。public
またはinternal
型を拡張する場合、追加された新しい型メンバーはデフォルトでinternal
アクセスレベルを持ちます。file-private
型を拡張する場合、追加された新しい型メンバーはデフォルトでfile-private
アクセスレベルを持ちます。private
型を拡張する場合、追加された新しい型メンバーはデフォルトでprivate
アクセスレベルを持ちます。
代わりに、拡張に明示的なアクセスレベル修飾子(たとえば、private
)をマークして、拡張内で定義されたすべてのメンバーに対して新しいデフォルトのアクセスレベルを設定できます。この新しいデフォルトは、拡張内の個々の型メンバーに対して引き続きオーバーライドできます。
プロトコル準拠を追加するために拡張を使用している場合、明示的なアクセスレベル修飾子を提供することはできません。代わりに、プロトコル自体のアクセスレベルが、拡張内の各プロトコル要件実装のデフォルトのアクセスレベルを提供します。
拡張内のプライベートメンバー
クラス、構造体、列挙型を拡張する拡張が、元の型の宣言と同じファイルにある場合、拡張内のコードは元の型の宣言の一部として書かれたかのように振る舞います。その結果、次のことができます。
- 元の宣言でプライベートメンバーを宣言し、同じファイル内の拡張からそのメンバーにアクセスします。
- 1つの拡張でプライベートメンバーを宣言し、同じファイル内の別の拡張からそのメンバーにアクセスします。
- 拡張でプライベートメンバーを宣言し、同じファイル内の元の宣言からそのメンバーにアクセスします。
この動作により、型にプライベートエンティティがあるかどうかに関係なく、コードを整理するために拡張を同じ方法で使用できます。たとえば、次のシンプルなプロトコルを考えます。
protocol SomeProtocol {
func doSomething()
}
次のように、拡張を使用してプロトコル準拠を追加できます。
struct SomeStruct {
private var privateVariable = 12
}
extension SomeStruct: SomeProtocol {
func doSomething() {
print(privateVariable)
}
}
ジェネリクス
ジェネリック型またはジェネリック関数のアクセスレベルは、ジェネリック型または関数自体のアクセスレベルと、型パラメータの型制約のアクセスレベルの最小値です。
型エイリアス
定義する型エイリアスは、アクセス制御の目的で別個の型として扱われます。型エイリアスは、それがエイリアスする型のアクセスレベルと同じかそれ以下のアクセスレベルを持つことができます。たとえば、private
型エイリアスは、private
、file-private
、internal
、public
、またはopen
型をエイリアスできますが、public
型エイリアスは、internal
、file-private
、またはprivate
型をエイリアスすることはできません。
Note
このルールは、プロトコル準拠を満たすために使用される関連型の型エイリアスにも適用されます。