Swift 6.0 beta 日本語化計画 : Swift 6.0 beta
宣言
型、演算子、変数、その他の名前と構成要素を導入します。
宣言 は、新しい名前を導入したり、プログラムに構築したりします。たとえば、宣言を使用して、関数やメソッドを導入したり、変数や定数を導入したり、列挙型、構造体、クラス、プロトコル型を定義したりします。また、宣言を使用して既存の名前付き型の動作を拡張したり、他の場所で宣言されているシンボルをプログラムにインポートすることもできます。
Swift では、ほとんどの宣言はまた、それらが実装されまたは宣言されたと同時に初期化されるという意味で定義でもあります。つまり、プロトコルはそのメンバを実装しないので、ほとんどのプロトコルメンバは宣言のみです。便宜上、区別は Swift では重要ではないため、宣言 の用語は、宣言と定義の両方をカバーしています。
Swift のソースファイル内のトップレベルのコードは、ゼロ個以上の文、宣言、および式で構成されています。デフォルトでは、ソースファイルのトップレベルで宣言されている変数、定数、および他の名前付きの宣言は、同じモジュールの一部である、すべてのソースファイル内のコードにアクセス可能です。アクセス制御レベル で説明したように、アクセスレベル修飾子で宣言をマークすることで、このデフォルトの動作をオーバーライドできます。
トップレベルのコードには、トップレベルの宣言と実行可能なトップレベルのコードの 2 種類あります。トップレベルの宣言は宣言のみで構成され、すべての Swift ソースファイルで許可されます。実行可能なトップレベルのコードには、宣言だけでなく文と式が含まれて、プログラムのトップレベルのエントリポイントとしてのみ許可されます。
実行可能な物を作成するためにコンパイルする Swift コードには、コードがファイルやモジュールにどのようにまとまっているかに関係なく、トップレベルのエントリポイントをマークするために以下のアプローチの最大 1 つを含めることができます:main 属性、NSApplicationMain 属性、UIApplicationMain 属性、main.swiftファイル、またはトップレベルの実行可能コードを含むファイルです。
コードブロック は、様々な宣言および制御構造体により使用され、文を一緒にグループ化します。これは以下の形式です:
{
<#statements#>
}
コードブロック内の 文 は、宣言、式、および他の種類の文を含み、ソースコードでの出現順に実行されます。
import 宣言 を使用すると、現在のファイルの外で宣言されたシンボルにアクセスできます。基本的な形式は、全体のモジュールを import します。それは import キーワードに続くモジュールの名前で構成されています。
import <#module#>
さらに詳細を提供すると、どのシンボルをインポートするかが制限されます。特定のサブモジュール、またはモジュールやサブモジュール内の特定の宣言を指定できます。この詳細形式を使用すると、インポートされたシンボル (およびそれを宣言するモジュールではない) のみが現在のスコープ内で使用可能になります。
import <#import kind#> <#module#>.<#symbol name#>
import <#module#>.<#submodule#>
定数の宣言 はプログラムに、定数の名前の付いた値を導入します。定数の宣言は、let キーワードを使用して宣言され、以下の形式です。
let <#constant name#> : <#type#> = <#expression#>
定数の宣言では、定数の名前 とイニシャライザ 式 の値との間の結合を不変と定義し、定数の値が設定された後は、変更できません。つまり、定数がクラスオブジェクトで初期化されている場合、オブジェクト自体は変更できますが、定数の名前とそれが参照するオブジェクトとの間の結合は変更できません。
定数がグローバルのスコープで宣言される場合、一つの値で初期化されなければなりません。定数の宣言が関数またはメソッドの文脈で発生すると、その値が最初に読み取られる前に値が設定されていることが保証されている限り、後で初期化することができます。コンパイラが定数の値は決して読み取られないことを証明できる場合、定数に値を設定する必要はまったくありません。この分析は 明確な初期化 と呼ばれ、コンパイラは値が読み取られる前に確実に設定されていることを証明します。
定数宣言がクラスまたは構造体宣言のコンテキストで発生する場合、定数プロパティ と見なされます。定数宣言は計算されたプロパティではないため、ゲッタやセッタはありません。
定数の宣言の 定数の名前 がタプルのパターンの場合、タプル内の各項目の名前は、イニシャライザ 式 の対応する値に結合されます。
この例では、firstNumber は値 10 の名前の付いた定数で、secondNumber は値 42 の名前の付いた定数です。いずれの定数も今や独立して使用できます。
型注釈 (:type) は、型の推測 で説明したように、定数名 の型が推測できる時、定数の宣言ではオプションです。
定数型プロパティを宣言するには、static 宣言修飾子で宣言をマークして下さい。クラスの定数型プロパティは、常に暗黙的に final です。サブクラスによるオーバーライドを許可または禁止する class または final 宣言修飾子でマークすることはできません。型プロパティは、型プロパティ で説明されています。
定数についての詳細とそれらを使用する場合のガイダンスは、定数と変数 及び 格納されたプロパティ を参照して下さい。
変数の宣言 は、プログラムに、変数の名前の付いた値を導入し、var キーワードを使用して宣言されます。
変数の宣言には、いくつかの形式があり、名前の付いた、変更可能な値、格納された、計算された変数やプロパティ、格納された変数とプロパティ監視者、および静的変数プロパティを含む、様々な種類を宣言します。使用に適した形式は、変数が宣言されたスコープと、宣言しようとする変数の種類に依存します。
オーバーライド(上書き) で説明したように、override 宣言修飾子で、サブクラスのプロパティ宣言をマークし、サブクラスのプロパティをオーバーライドできます。
以下の形式で、格納された変数と格納された変数のプロパティを宣言します。
var <#variable name#> : <#type#> = <#expression#>
グローバルなスコープで変数の宣言のこの形式を定義し、関数のローカルなスコープや、クラスまたは構造体の宣言の文脈で定義して下さい。この形式の変数の宣言がグローバルなスコープまたは関数のローカルなスコープでなされると、それは 格納された変数 として参照されます。それがクラスまたは構造体の宣言の文脈の中で宣言された場合には、格納された変数のプロパティ として参照されます。
イニシャライザ 式 はプロトコル宣言には存在できませんが、他のすべての文脈では、イニシャライザ 式 はオプションです。つまり、イニシャライザ 式 が存在しない場合、変数の宣言は、明示的な型注釈 (: type) を含めなければなりません。
定数宣言と同様に、変数宣言で初期化式を省略した場合、変数は最初にそれが読み取られる前に値が設定されていなければなりません。また、定数宣言と同様に、変数名 がタプルパターンの場合、タプル内の各項目の名前は初期化 式 の対応する値に結束されます。
それらの名前が示唆するように、格納された変数または格納された変数プロパティの値は、メモリに格納されます。
以下の形式で計算された変数または計算されたプロパティを宣言します。
var <#variable name#> : <#type#> {
get {
<#statements#>
}
set(<#setter name#>) {
<#statements#>
}
}
グローバルなスコープでこの形式での変数の宣言を定義し、関数のローカルなスコープや、クラス、構造体、列挙型、または拡張機能の宣言の文脈で定義して下さい。この形式での変数の宣言がグローバルなスコープまたは関数のローカルなスコープで宣言されている場合、それは 計算された変数 として参照されます。クラス、構造体、または拡張機能の宣言の文脈内で宣言された場合には、計算されたプロパティ として参照されます。
ゲッタは、値を読み出すために使用され、セッタは、値を書き込むために使用されます。セッタ節はオプションであり、ゲッタのみが必要ならば、両方の節を省略でき、読み取り専用の計算されたプロパティ で説明したように、直接、要求された値を単に返す事ができます。しかし、セッタ節を提供するならば、ゲッタ節も提供しなければなりません。
セッタの名前 と、取り囲む括弧はオプションです。セッタの名前を提供する場合は、セッタへのパラメータ名として使用されます。セッタの名前を提供しない場合は、セッタ宣言の省略形 で説明したように、セッタへのデフォルトのパラメータ名は newValue です。
格納された名前付きの値や格納された変数プロパティとは異なり、計算された名前付きの値や、計算されたプロパティの値は、メモリに格納されません。
計算されたプロパティの詳細と例を見るには、計算されたプロパティ を参照してください。
willSet と didSet 監視者で、格納された変数またはプロパティをも宣言できます。監視者 (observer) で宣言された格納された変数やプロパティは、以下の形式です。
var <#variable name#> : <#type#> = <#expression#> {
willSet(<#setter name#>) {
<#statements#>
}
didSet(<#setter name#>) {
<#statements#>
}
}
グローバルなスコープで変数の宣言をこの形式で定義し、関数のローカルなスコープで定義するか、クラスまたは構造体の宣言の文脈で定義して下さい。この形式の変数の宣言がグローバルなスコープまたは関数のローカルなスコープで宣言された場合、監視者は、格納された変数の監視者 として参照されます。クラスまたは構造体の宣言の文脈の中で宣言された場合、監視者は、プロパティの監視者 として参照されます。
全ての格納されたプロパティに、プロパティの監視者を追加できます。また、プロパティ監視者のオーバーライド で説明したように、サブクラス内のプロパティをオーバーライドすることで (格納されたまたは計算された) 全てのの継承されたプロパティにも、プロパティ監視者を追加できます。
イニシャライザ 式 は、クラスまたは構造体の宣言の文脈ではオプションですが、他の場所ではどこでも必須です。型 注釈は、型がイニシャライザ 式 から推測可能であればオプションです。この式は、プロパティの値を初めて読み取るときに評価されます。プロパティの初期値を読み取らずに上書きすると、この式は、プロパティに初めて書き込む前に評価されます。
willSet と didSet 監視者は、変数またはプロパティの値が設定されているときに監視する (かつ適切に対応する) 方法を提供します。変数またはプロパティが最初に初期化されるとき、監視者は呼び出されません。代わりに、それらは値が初期化文脈の外側で設定された時にのみ呼び出されます。
willSet 監視者は、変数またはプロパティの値が設定される直前に呼び出されます。新しい値は定数として willSet 監視者に渡されるので、それは willSet 節の実装中には変更できません。didSet 監視者は新しい値が設定された直後に呼び出されます。willSet 監視者とは対照的に、変数またはプロパティの古い値は、まだそれにアクセスする必要がある場合に didSet 監視者に渡されます。つまり、自身の didSet 監視者節内の変数またはプロパティに値を代入する場合、代入した新しい値が、ちょうど設定された値を置き換え、willSet 監視者に渡されます。
セッタの名前 と willSet とdidSet 節内を囲むカッコはオプションです。セッタの名前を提供する場合、それらは willSet と didSet 監視者へのパラメータ名として使用されます。セッタの名前を提供しない場合、willSet 監視者に対するデフォルトのパラメータ名は newValue になり、didSet 監視者へのデフォルトのパラメータ名は oldValue になります。
willSet 節を提供する際には didSet 節はオプションです。同様に、didSet 節を提供する際には、willSet 節はオプションです。
didSet 監視者の本体が古い値を参照している場合、古い値を使用可能にするために、監視者の前にゲッタが呼び出されます。それ以外の場合、新しい値はスーパークラスのゲッタを呼び出さずに格納されます。以下の例は、スーパークラスによって定義され、監視者を追加するためにそのサブクラスによってオーバーライドされる計算されたプロパティを示しています。
詳細とプロパティ監視者を使用する方法の例については、プロパティ監視者 を参照してください。
型変数プロパティを宣言するには、static 宣言修飾子で宣言をマークして下さい。サブクラスがスーパークラスの実装をオーバーライドするのを許す代わりに、クラスは型の計算されたプロパティを class 宣言修飾子でマークできます。型プロパティは、型プロパティ で議論しました。
型エイリアス宣言 は、プログラムに既存の型の、名前のついたエイリアスを導入します。型エイリアス宣言は、キーワード typealias を使用し、以下のような形式で宣言します:
typealias <#name#> = <#existing type#>
型エイリアスが宣言された後は、エイリアスの 名前 はプログラムのどこでも 既存の型 の代わりに使用できます。既存の型 は、名前付きの型または複合の型にできます。型エイリアスは、新しい型を作成することはありません。それは単に既存の型を名前で参照することを許可するだけです。
型エイリアス宣言は、汎用パラメータを使用して既存の汎用型に名前を付けることができます。型エイリアスは、既存の型の汎用パラメータの一部またはすべてに具体的な型を提供できます。例えば:
型エイリアスが汎用パラメータで宣言されている場合、それらのパラメータの制約は、既存の型の汎用パラメータの制約と正確に一致しなければなりません。例えば:
型エイリアスと既存の型は交換して使用できるため、型エイリアスは追加の汎用制約を導入できません。
型エイリアスは、宣言からすべての汎用パラメータを省略して、既存の型の汎用パラメータを転送できます。たとえば、ここで宣言されている Diccionario の型エイリアスは、Dictionary と同じ汎用パラメータと制約を持ちます。
プロトコル宣言の中で、型エイリアスは、頻繁に使用される型に、短くてもっと便利な名前を付けることができます。例えば:
この型エイリアスがなければ、sum 関数は関連する型を T.Element の代わりに T.Iterator.Element として参照しなければならないでしょう。
プロトコルに関連した型の宣言 も参照してください。
関数の宣言 は、プログラムに関数やメソッドを導入します。クラス、構造体、列挙型、またはプロトコルの文脈で宣言された関数は、メソッド として参照されます。関数の宣言は、キーワード func を使用して宣言し、以下のような形式を持っています:
func <#function name#>(<#parameters#>) -> <#return type#> {
<#statements#>
}
関数が Void の戻り値の型を持っている場合、以下のように、戻り値の型を省略できます:
func <#function name#>(<#parameters#>) {
<#statements#>
}
各パラメータの型は含まれなければならないーそれは推測できません。パラメータの型の前に inout を書き込むと、関数のスコープ内でそのパラメータを変更できます。in-out パラメータについては、以下の In-Out パラメータ で詳しく議論しています。
その 文 に単一の式のみが含まれる関数の宣言は、その式の値を返すと理解されます。この暗黙の戻り値の構文は、式の型と関数の戻り値の型が Void ではなく、何も case のない Never のような列挙型でない場合にのみ考慮されます。
関数は、関数の戻り値の型としてタプル型を使用して複数の値を返すことができます。
関数の定義は、別の関数の宣言内に表示できます。このような関数は、入れ子になった関数 として知られています。
入れ子になった関数は、決してエスケープしないことが保証されている値 (in-out パラメータなど) をキャプチャしている場合、またはエスケープしていない関数の引数として渡された場合はエスケープしません。それ以外の場合は、入れ子になった関数はエスケープする関数です。
入れ子になった関数の詳細については、入れ子になった関数 を参照してください。
関数のパラメータは、各パラメータがいくつかの形式のいずれか1つを持っている、カンマ区切りのリストです。関数呼び出しの引数の順序は、関数の宣言内のパラメータの順序と一致しなければなりません。パラメータリストの最も簡単なエントリの形式は以下のとおりです。
<#parameter name#>: <#parameter type#>
パラメータには関数本体内で使用される名前と、関数またはメソッドを呼び出すときに使用される引数のラベルがあります。デフォルトでは、パラメータ名も引数ラベルとして使用されます。例えば:
引数ラベルのデフォルトの動作は、以下のいずれか 1 つの形式で上書き(オーバーライド)できます。
<#argument label#> <#parameter name#>: <#parameter type#>
_ <#parameter name#>: <#parameter type#>
パラメータ名の前の名前は、パラメータに明示的な引数ラベルを与え、これはパラメータ名とは異なる場合があります。対応する引数は、関数またはメソッドの呼び出し内で与えられた引数ラベルを使用しなければなりません。
パラメータ名の前のアンダースコア (_ ) は、引数のラベルを抑制します。対応する引数は、関数またはメソッドの呼び出しでラベルを持ってはなりません。
パラメータ修飾子 は、引数が関数に渡される方法を変更します。
パラメータ修飾子を使用するには、引数の型の前に inout、borrowing、または consuming を記述します。
デフォルトでは、Swift の関数引数は値で渡されます。関数内で行われた変更は呼び出し元には表示されません。代わりに in-out パラメータを作成するには、inout パラメータ修飾子を適用します。
in-out パラメータを含む関数を呼び出す場合、関数呼び出しが引数の値を変更できることを示すために、in-out 引数の前にアンパサンド (&) を付けなければなりません。
In-Out パラメータは、以下のように渡されます。
この動作は、コピーインコピーアウト または 値の結果による呼び出し と呼ばれます。たとえば、計算されたプロパティまたは監視者を持つプロパティが in-out パラメータとして渡されると、そのゲッタは関数呼び出しの一部として呼び出され、そのセッタは関数の戻り値の一部として呼び出されます。
最適化として、引数がメモリ内の物理アドレスに格納された値である場合、関数本体の内部と外部の両方で同じメモリ位置が使用されます。最適化された動作は、参照による呼び出し として知られます。コピーするオーバーヘッドを除去しながら、コピーインコピーアウトモデルのすべての要件をこれは満たします。最適化の有無にかかわらず、正しく動作するように、参照による呼び出しの最適化に依存せずに、コピーインコピーアウトによって与えられたモデルを使用してコードを記述して下さい。
元の値が現在のスコープで使用可能であったとしても、in-out 引数として渡された値には関数内ではアクセスしないでください。元の値へのアクセスは値の同時アクセスであり、これはメモリ排他性に違反します。
同じ理由で、複数の in-out パラメータに同じ値を渡すこともできません。
メモリの安全性とメモリの排他性の詳細については、メモリの安全性 を参照してください。
in-out パラメータをキャプチャするクロージャまたは入れ子にされた関数は、エスケープしてはいけません。in-out パラメータを変更せずにキャプチャする必要がある場合は、キャプチャリストを使用して明示的にパラメータを変更せずにキャプチャします。
in-out パラメータをキャプチャして変更する必要がある場合は、関数が返す前にすべての変更が完了していることを保証するマルチスレッドのコードのように、明示的なローカルコピーを使用します。
in-out パラメータの詳細と例については、In-Out パラメータ を参照してください。
デフォルトでは、Swift は一連のルールを使用して、関数呼び出し間でオブジェクトの寿命を自動的に管理し、必要に応じて値をコピーします。デフォルトのルールは、ほとんどの場合にオーバーヘッドを最小限に抑えるように設計されています。より具体的な制御が必要な場合は、borrowing または consuming パラメータ修飾子を適用できます。この場合、copy を使用して copy 操作を明示的にマークします。
デフォルトのルールを使用するかどうかに関係なく、Swift は、オブジェクトの寿命と所有権が全てのケースで正しく管理されることを保証します。これらのパラメータ修飾子は、特定の使用パターンの相対的な効率にのみ影響し、正確性には影響しません。
borrowing 修飾子は、関数がパラメータの値を保持しないことを示します。この場合、呼び出し元はオブジェクトの所有権とオブジェクトの寿命の責任を維持します。borrowing を使用すると、関数がオブジェクトを一時的にのみ使用する場合にオーバーヘッドが最小限に抑えられます。
たとえば、関数がパラメータの値をグローバル変数に格納して保持する必要がある場合は、copy を使用してその値を明示的にコピーします。
逆に、consuming パラメータ修飾子は、関数が値の所有権を取得し、関数が戻る前に値を格納するか破棄するかの責任を受け入れることを示します。
consuming を使用すると、関数呼び出し後に呼び出し元がオブジェクトを使用する必要がなくなった場合にオーバーヘッドが最小限に抑えられます。
関数呼び出し後に、コピー可能なオブジェクトを引き続き使用すると、コンパイラは関数呼び出しの前にそのオブジェクトのコピーを自動的に作成します。
inout とは異なり、関数を呼び出すときに borrowing や consuming パラメータでの特別な表記は必要ありません。
borrowing または consuming のいずれかを明示的に使用することは、実行時の所有権管理のオーバーヘッドをより厳密に制御する意図を示します。コピーによって予期しない実行時の所有権操作が発生する可能性があるため、明示的な copy キーワードを使用しない限り、これらの修飾子のいずれかでマークされたパラメーターはコピーできません。
パラメータは無視することができ、可変個の値を取り、デフォルト値を提供し、以下の形式を使用します:
_ : <#parameter type#>
<#parameter name#>: <#parameter type#> ...
<#parameter name#>: <#parameter type#> = <#default argument value#>
アンダースコア (_ ) パラメータは、明示的に無視され、関数の本体内ではアクセスできません。
基本型の名前のパラメータの直後に続く3つのドット (... ) は、可変引数パラメータとして理解されます。可変引数パラメータの直後に続くパラメータには、引数ラベルがなければなりません。関数は、複数の可変パラメータを持つ事ができます。可変パラメータは、基本型名の要素を含む配列として扱われます。例えば、可変パラメータ Int... は [Int] として扱われます。可変パラメータを使用する例については、可変パラメータ を参照してください。
等号 (=) を伴ったパラメータと、その型の後の式は、与えられた式のデフォルト値を持っていると理解されます。関数が呼び出されたときに、与えられた式は評価されます。関数を呼び出すときにパラメータを省略すると、デフォルト値が代わりに使用されます。
self を変更する、列挙型または構造体上のメソッドは mutating 宣言修飾子でマークされなければなりません。
スーパークラスのメソッドをオーバーライドするメソッドは、override 宣言修飾子でマークされなければなりません。override 修飾子なしでメソッドをオーバーライドするか、スーパークラス・メソッドをオーバーライドしないメソッドで override 修飾子を使用すると、コンパイル時エラーになります。
型のインスタンスではなく、型に関連したメソッドは、列挙型と構造体では static 宣言修飾子、またはクラスでは static または class 宣言修飾子でマークされなければなりません。class 宣言修飾子でマークされたクラス型メソッドは、サブクラスの実装によってオーバーライドできます。class final または static とマークされたクラス型メソッドはオーバーライドできません。
特別な名前を持ついくつかのメソッドは、関数呼び出し構文のシンタックスシュガーを有効にします。型がこれらのメソッドの 1 つを定義する場合、その型のインスタンスは関数呼び出し構文で使用できます。関数呼び出しは、そのインスタンスで特別に名前が付けられたメソッドの 1 つへの呼び出しであると理解されます。
クラス、構造体、または列挙型は、dynamicCallable で説明した dynamicallyCall(withArguments:) メソッドか dynamicallyCall(withKeywordArguments:) メソッドを定義するか、下記のように call-as-function (関数として呼び出す) メソッドを定義することにより、関数呼び出し構文をサポートできます。型が関数として呼び出すメソッドと dynamicCallable 属性で使用されるメソッドの一つの両方を定義している場合、コンパイラはどちらかのメソッドを使用できる状況で関数として呼び出すメソッドを優先します。
call-as-function (関数として呼び出す) メソッドの名前は callAsFunction( )、または callAsFunction( で始まり、ラベル付きまたはラベルなしの引数を追加する別の名前です。たとえば、callAsFunction(_:_:) および callAsFunction(something:) も有効な call-as-function (関数として呼び出す) メソッドの名前です。
以下の関数呼び出しは同等です。
call-as-function (関数として呼び出す) メソッドと dynamicCallable 属性からのメソッドは、型システムにコード化する情報量と実行時に可能な動的動作の量との間で異なるトレードオフを行います。call-as-function (関数として呼び出す) メソッドを宣言するときは、引数の数と各引数の型とラベルを指定します。dynamicCallable 属性のメソッドは、引数の配列を保持するために使用される型のみを指定します。
call-as-function (関数として呼び出す) メソッド、または dynamicCallable 属性からのメソッドを定義すると、その型のインスタンスを、関数呼び出し式以外の文脈の関数であるかのように使用することはできません。例えば:
subscript(dynamicMemberLookup:) サブスクリプトを使用すると、dynamicMemberLookup で説明したように、メンバー検索のシンタックスシュガーが有効になります。
エラーを throw できる関数とメソッドは、throws キーワードでマークされなければなりません。これらの関数とメソッドは、throw する関数 と throw するメソッド として知られています。これらは以下の形式です:
func <#function name#> ( <#parameters#> ) throws -> <#return type#> {
<#statements#>
}
特定のエラーの型を throw する関数の形式は以下のとおりです。
func <#function name#>(<#parameters#>) throws(<#error type#>) -> <#return type#> {
}
throw する関数またはメソッドへの呼び出しは、try または try! 式で包み込まなければなりません (つまり、try または try! 演算子のスコープ内にあります)。
関数の型には、エラーを throw できるかどうか、およびどの型のエラーを throw するかが含まれます。このサブタイプの関係は、たとえば、エラーを throw しない関数を、エラーを throw する関数が期待されるコンテキストで使用できることを意味します。エラーを throw する関数の型の詳細については、関数の型 を参照してください。明示的な型を持つエラーの操作例については、エラーの型の指定 を参照してください。
関数がエラーを throw できるかどうかだけに基づいて関数をオーバーロードすることはできません。つまり、関数の パラメータ がエラーを throw できるかどうかに基づいて、関数をオーバーロードできます。
throw するメソッドは throw しないメソッドをオーバーライドできず、また throw するメソッドは throw しないメソッドのプロトコル要件を満たすことができません。つまり、throw しないメソッドは throw するメソッドをオーバーライドでき、throw しないメソッドは throw するメソッドのプロトコル要件を満たすことができます。
rethrows キーワードで関数またはメソッドを宣言すると、その関数のパラメータの1つがエラーを throw する場合にのみエラーを throw することを示すことができます。これらの関数とメソッドは、rethrow する関数 と rethrow するメソッド として知られています。rethrow する関数とメソッドは、少なくとも1つの throw する関数パラメータを持っていなければなりません。
rethrow する関数またはメソッドには、catch 節の中にのみ throw 文を含めることができます。これにより、 do-catch 文内で throw する関数を呼び出し、異なるエラーを throw する事により catch 節内のエラーを処理できます。さらに、catch 節は、rethrow する関数の throw するパラメータの1つによって throw されたエラーのみを処理しなければなりません。たとえば、catch 節が alwaysThrows( ) によって throw されたエラーを処理するため、以下の例は無効です。
throw するメソッドは rethrow するメソッドをオーバーライドできませんし、throw するメソッドは rethrow するメソッドのプロトコル要件を満たすことができません。つまり、rethrow するメソッドは throw するメソッドをオーバーライドでき、rethrow するメソッドは throw するメソッドのプロトコル要件を満たすことができます。
rethrow の代わりとして、汎用コードで特定のエラーの型を throw する方法もあります。例えば:
エラーを伝播するこのアプローチでは、エラーに関する型情報が保持されます。ただし、関数を rethrow とマークする場合とは異なり、このアプローチでは関数が同じ型のエラーを throw することを防ぐことはできません。
非同期で実行される関数とメソッドは、async キーワードでマークされなければいけません。これらの関数およびメソッドは、非同期関数 および 非同期メソッド として知られています。それらの形式は以下のとおりです。
func <#function name#>(<#parameters#>) async -> <#return type#> {
<#statements#>
}
非同期関数またはメソッドの呼び出しは、await 式で包み込まなければなりません。つまり、await 演算子のスコープ内になければなりません。
async キーワードは関数の型の一部であり、同期関数は非同期関数のサブタイプです。その結果、非同期関数が予期されるコンテキストで同期関数を使用できます。たとえば、非同期メソッドを同期メソッドでオーバーライドでき、非同期メソッドを要求するプロトコル要件を同期メソッドで満たすことができます。
関数が非同期かどうかに基づいて関数をオーバーロードできます。呼び出し側では、コンテキストによってどのオーバーロードが使用されるかが決まります。非同期コンテキストでは非同期関数が使用され、同期コンテキストでは同期関数が使用されます。
非同期メソッドは同期メソッドをオーバーライドできません。また、非同期メソッドは同期メソッドのプロトコル要件を満たすことはできません。つまり、同期メソッドは非同期メソッドをオーバーライドでき、同期メソッドは非同期メソッドのプロトコル要件を満たすことができます。
Swift は、関数またはメソッドが呼び出し側に返さないことを示す Never 型を定義しています。Never の戻り値の型を持つ関数とメソッドは、返さない (nonreturning) と呼ばれます。返さない関数とメソッドは、回復不可能なエラーを引き起こすか、無限に続く一連の作業を開始するかのどちらかです。つまり、呼び出し直後に実行されるはずのコードは決して実行されない事を意味します。throw と rethrow する関数は、それらが返さなかったとしても、プログラム制御を適切な catch ブロックに転送できます。
Guard 文 で説明したように、guard 文の else 節を終結させるために、返さない関数またはメソッドを呼び出すことができます。
返さないメソッドをオーバーライドすることはできますが、新しいメソッドはその戻り値の型と返さない動作を保持しなければなりません。
列挙型の宣言 は、プログラムに名前の付いた列挙型を導入します。
列挙型の宣言には、2つの基本的な形式があり、enum キーワードを使用して宣言されます。列挙型の本体は、ゼロ個以上の値ー 列挙型の case と呼ばれます– を含む形式と、以下の任意の数の宣言でなされます:計算されたプロパティ、インスタンス・メソッド、型メソッド、イニシャライザ、型エイリアス、さらには他の列挙型、構造体、クラス、およびアクターの宣言です。列挙型の宣言は、デイニシャライザまたはプロトコル宣言を含めることはできません。
列挙型は、プロトコルをいくらでも採用できますが、クラス、構造体、または他の列挙型からは継承できません。
クラスや構造体とは異なり、列挙型には、暗黙的に提供されるデフォルトのイニシャライザはありません。すべてのイニシャライザは、明示的に宣言されなければなりません。イニシャライザは、列挙型内の他のイニシャライザにデリゲートできますが、初期化プロセスは、self に列挙型の case の一つをイニシャライザが代入した後にのみ、完了します。
構造体のように、しかしクラスとは異なり、列挙型は、値型です。変数や定数に代入されたとき、または関数呼び出しで引数として渡されたとき、列挙型のインスタンスはコピーされます。値型の詳細については、構造体と列挙型は値型 を参照してください。
拡張機能の宣言 で議論したように、拡張機能の宣言で列挙型の動作を拡張できます。
以下の形式で、任意の型の列挙型の case を含む列挙型を宣言できます。
enum <#enumeration name#> : <#adopted protocols#> {
case <#enumeration case 1#>
case <#enumeration case 2#> ( <#associated value types#> )
}
この形式で宣言された列挙型は時々、他のプログラミング言語では 差別された共用体 (discriminated unions) と呼ばれています。
この形式では、それぞれの case ブロックは、case キーワードに引き続き、カンマで区切られた1つ以上の列挙型の case で構成されます。各 case の名前は固有でなければなりません。各 case はまた、与えられた型の値を格納するように指定できます。これらの型は、直後に case の名前が続く、関連した値の型 のタプルで指定されています。
関連した値を格納する列挙型の case は、指定された関連した値を持つ列挙型のインスタンスを作成する関数として使用できます。関数と同様に、列挙型 case への参照を取得し、後でコードに適用できます。
詳細および関連した値型の case の例に関しては、関連する値 を参照してください。
列挙型は再帰的構造体を持つことができます。つまり、列挙型自体のインスタンスである関連した値を持つ case を持つことができます。しかし、列挙型のインスタンスには値の意味があります。つまり、メモリ内に固定したレイアウトがあることを意味します。再帰をサポートするために、コンパイラは間接のレイヤを挿入しなければなりません。
特定の列挙型の case の間接化を有効にするには、それを indirect 宣言修飾子でマークします。indirect (間接の) case は関連する値を持たなければなりません。
関連する値を持つ列挙型の全ての case で間接を有効にするには、列挙型全体を indirect 修飾子でマークして下さい。これは、列挙型が各々を indirect 修飾子でマークする必要がある case が多数ある場合に便利です。
indirect 修飾子でマークされた列挙型は、関連する値を持つ case とそうでない case が混在することがあります。それは、indirect 修飾子でもマークされている case を含むことはできないと言う事です。
以下の形式で、同じ基本型の列挙型の case を含む列挙型を宣言できます。
enum <#enumeration name#> : <#raw-value type#> , <#adopted protocols#> {
case <#enumeration case 1#> = <#raw value 1#>
case <#enumeration case 2#> = <#raw value 2#>
}
この形式では、それぞれの case ブロックは case キーワードで構成され、カンマで区切られた1つ以上の列挙型の case が続きます。最初の形式での case とは異なり、それぞれの case は、同じ基本型の 生の値 と呼ばれる基本的な値を持っています。これらの値の型は 生の値型 で指定されており、整数、浮動小数点数、文字列、または一つの文字を表さなければなりません。具体的には、生の値型 は Equatable プロトコルと以下のプロトコルのいずれか1つに準拠しなければなりません:整数リテラル用の ExpressibleByIntegerLiteral、浮動小数点リテラル用の ExpressibleByFloatLiteral、任意の文字数を含む文字列リテラル用の ExpressibleByStringLiteral、唯一つの文字を含む文字列リテラル用の ExpressibleByUnicodeScalarLiteral または ExpressibleByExtendedGraphemeClusterLiteral です。それぞれの case には固有の名前がなければならず、固有の生の値が割り当てられていなければなりません。
生の値型が Int として指定されており、明示的に case に値を割り当てていない場合は、暗黙的に 0,1,2, などの値が割り当てられます。Int 型の割り当てられていない各 case には、前の case の生の値から自動的にインクリメント (増分) された生の値が暗黙的に割り当てられます。
上記の例では、ExampleEnum.a の生の値は 0 で、ExampleEnum.b の値は 1 です。ExampleEnum.c の値が明示的に 5 に設定されているため、ExampleEnum.d の値は自動的に 5 から増分され、したがって、6 です。
生の値型が String として指定されており、明示的に値を case に割り当てていない場合、割り当てられていない各 case は、その case の名前と同じテキストの文字列が暗黙的に割り当てられます。
上記の例では、GamePlayMode.cooperative の生の値は "cooperative" で、GamePlayMode.individual の生の値は "individual" で、GamePlayMode.competitive の生の値は "competitive" です。
生の値型の case のある列挙型は、Swift 標準ライブラリで定義されている RawRepresentable プロトコルに暗黙的に準拠しています。結果として、それらは rawValue プロパティを持ち、init?(rawValue: RawValue) の署名で、失敗可能なイニシャライザを持っています。ExampleEnum.b.rawValue のように、列挙型 case の生の値にアクセスするには rawValue プロパティを使用できます。optional の case を返す ExampleEnum(rawValue: 5) のように、それが一つであれば、列挙型の失敗可能なイニシャライザを呼び出すことによって、対応する case を見つけて生の値を使用することもできます。詳細について、及び生の値型を持つ case の例は、生の値 を参照してください。
列挙型の case を参照するには、EnumerationType.enumerationCase のように、ドット (.) 構文を使用します。列挙型が文脈から推測できるときには、列挙型の構文 および 暗黙のメンバ式 で説明したように、(ドットはまだ必要ですが)それを省略できます。
switch 文で列挙型の値と一致 で示したように、列挙型の case の値を確認するには、switch 文を使って下さい。列挙型 case のパターン で説明したように、列挙型は switch 文の case ブロックで列挙型 case パターンに対してパターン照合されます。
構造体の宣言 は、プログラムに名前の付いた構造体の型を導入します。構造体の宣言は、struct キーワードを使用して宣言し、以下のような形式です:
struct <#structure name#> : <#adopted protocols#> {
<#declarations#>
}
構造体の本体は、ゼロ個以上の 宣言 を含んでいます。これらの 宣言 は、格納されたプロパティと計算されたプロパティの両方、型プロパティ、インスタンスメソッド、型メソッド、イニシャライザ、サブスクリプト、型エイリアス、さらには他の構造体、クラス、アクター、および列挙型の宣言を含めることができます。構造体の宣言は、デイニシャライザまたはプロトコルの宣言を含めることはできません。議論と宣言の様々な種類を含む構造体のいくつかの例については、構造体とクラス を参照してください。
構造体型は、プロトコルをいくつでも採用することができますが、クラス、列挙型、または他の構造体からは継承することはできません。
以前に宣言された構造体のインスタンスを作成するには3つの方法があります。
構造体の宣言されたプロパティの初期化プロセスは、 初期化 で説明しました。
プロパティにアクセス で説明したように、構造体インスタンスのプロパティは、ドット (.) 構文を使用してアクセスできます。
構造体は値型であり、変数や定数に代入されたとき、または関数呼び出しに引数として渡されたときには構造体のインスタンスはコピーされます。値型の詳細については、構造体と列挙型は値型 を参照してください。
拡張機能の宣言 で議論したように、拡張機能の宣言で構造体型の動作を拡張できます。
クラスの宣言 は、プログラムに名前の付いたクラス型を導入します。クラスの宣言は、class キーワードを使用して宣言し、以下のような形式です:
class <#class name#> : <superclass#> , <#adopted protocols#> {
<#declarations#>
}
クラスの本体は、ゼロ個以上の 宣言 を含んでいます。これらの 宣言 は、格納されたプロパティ、計算されたプロパティの両方、インスタンスメソッド、型メソッド、イニシャライザ、一つのデイニシャライザ、サブスクリプト、型エイリアス、さらには他のクラス、構造体、アクター、および列挙型の宣言を含めることができます。クラスの宣言は、プロトコルの宣言を含めることはできません。議論や宣言の様々な種類を含むクラスのいくつかの例については、構造体とクラス を参照してください。
クラス型は、1つの親クラス、その スーパークラス からしか継承することができませんが、いくつでもプロトコルを採用できます。スーパークラス は、クラス名 とコロンに続いて最初に現れ、全ての 採用したプロトコル が続きます。汎用クラスは、他の汎用および非汎用クラスから継承できますが、非汎用クラスは、他の非汎用クラスからのみ継承できます。コロンの後に、汎用スーパークラスのクラス名を記述するときは、その汎用パラメータ句を含め、その汎用クラスのフルネームを含めなければなりません。
イニシャライザ宣言 で説明したように、クラスは指定イニシャライザと、コンビニエンス・イニシャライザを持てます。クラスの指定イニシャライザは、クラスの宣言されたすべてのプロパティを初期化しなければならず、そのスーパークラスの指定イニシャライザのいずれかを呼び出す前にそうしなければなりません。
クラスは、そのスーパークラスのプロパティ、メソッド、サブスクリプト、およびイニシャライザをオーバーライドできます。オーバーライドされたプロパティ、メソッド、サブスクリプト、および指定イニシャライザは override 宣言修飾子でマークされなければなりません。
サブクラスが、スーパークラスのイニシャライザを実装するように要求するには、required 宣言修飾子でスーパークラスのイニシャライザをマークして下さい。そのイニシャライザのサブクラスの実装も required 宣言修飾子でマークされなければなりません。
スーパークラス で宣言されたプロパティとメソッドは、現在のクラスによって継承されますが、スーパークラス 内で宣言された指定イニシャライザは、自動イニシャライザの継承 で説明した条件をサブクラスが満たす場合にのみ継承されます。Swift のクラスはユニバーサル基本クラスから継承しません。
以前に宣言されたクラスのインスタンスを作成するには2つの方法があります。
プロパティにアクセス で説明したようにドット (.) 構文でクラスインスタンスのプロパティにアクセスできます。
クラスは、参照型です。クラスのインスタンスは、変数や定数に代入されたとき、または関数呼び出しの引数として渡されたときには、コピーされるのではなく、参照されます。参照型については、構造体と列挙型は値型 を参照してください。
拡張機能の宣言 で議論したように、拡張機能の宣言でクラス型の動作を拡張することができます。
Actor (アクター) の宣言 は、名前付きのアクターの型をプログラムに導入します。アクターの宣言は、actor キーワードを使用して宣言され、次の形式になります。
actor <#actor name#>: <#adopted protocols#> {
<#declarations#>
}
アクターの本体には 0 個以上の 宣言 が含まれています。これらの 宣言 には、格納されたプロパティと計算されたプロパティの両方、インスタンスメソッド、型メソッド、イニシャライザ、単一のデイニシャライザ、サブスクリプト、型エイリアス、さらには他のクラス、構造体、列挙型宣言を含めることができます。さまざまな種類の宣言を含むアクターの説明といくつかの例については、アクター を参照してください。
アクターの型は任意の数のプロトコルを採用できますが、クラス、列挙型、構造体、または他のアクターから継承することはできません。ただし、@objc 属性でマークされたアクターは、暗黙的に NSObjectProtocol プロトコルに準拠し、NSObject のサブタイプとして Objective-C 実行時環境に公開されます。
以前に宣言されたアクターのインスタンスを作成するには、以下の 2 つの方法があります。
デフォルトでは、アクターのメンバはそのアクターに孤立しています。メソッドの本体やプロパティのゲッタなどのコードは、そのアクター上で実行されます。アクター内のコードは、同じアクター上で既に実行されているため、アクターを同期的に操作できますが、アクターの外側のコードは、このコードが別のアクター上でコードを非同期的に実行していることを示すために、アクターに await マークを付けなければなりません。キーパスは、アクターの孤立したメンバを参照することはできません。アクターに孤立された格納されたプロパティは、in-out パラメータとして同期関数に渡すことができますが、非同期関数には渡すことができません。
アクターはまた孤立していないメンバを持つこともでき、その宣言は nonisolated キーワードでマークされます。孤立していないメンバはアクターの外部のコードのように実行します。それはアクターのどの孤立状態も操作できず、呼び出し元はそれを使用するときに await マークを付けません。
アクターのメンバは、孤立していないまたは非同期である場合にのみ @objc 属性でマークできます。
アクターの宣言されたプロパティを初期化するプロセスについては、初期化 で説明されています。
アクターのインスタンスのプロパティには、プロパティにアクセス で説明されているように、ドット (.) 構文を使用してアクセスできます。
アクターは参照型です。アクターのインスタンスは、変数または定数に代入されるとき、または関数呼び出しに引数として渡されるときに、コピーされるのではなく参照されます。参照型の詳細については、クラスは参照型 を参照してください。
拡張機能の宣言 で説明されているように、拡張機能の宣言を使用してアクターの型の動作を拡張できます。
プロトコルの宣言 は、プログラムに名前の付いたプロトコル型を導入します。プロトコルの宣言は protocol キーワードを使用して宣言し、以下の形式です:
protocol <#protocol name#> : <#inherited protocols#> {
<#protocol member declarations#>
}
プロトコル宣言は、グローバルのスコープで表示することも、汎用型でない、または汎用型でない関数内に入れ子にすることもできます。
プロトコルの本体は、ゼロ個以上の プロトコル·メンバ宣言 を含み、プロトコルが満たさなければならない全ての型が採用している準拠要件を記述します。具体的には、プロトコルは、準拠する型が、特定のプロパティ、メソッド、イニシャライザ、およびサブスクリプトを実装しなければならないことを宣言できます。プロトコルはまた、プロトコルのさまざまな宣言間の関係を指定できる、関連する型 と呼ばれる型エイリアスの特別な種類も宣言できます。プロトコルメンバ宣言 は以下に詳細に説明します。
プロトコル型は、他のプロトコルからいくつでも継承できます。プロトコル型が他のプロトコルから継承した場合、それら他のプロトコルからの一連の要件は集約され、そして現在のプロトコルから継承する全ての型は、これらすべての要件に準拠しなければなりません。プロトコルの継承を使用する方法の例については、プロトコルの継承 を参照してください。
その型の拡張機能の宣言でプロトコルを採用することにより、以前に宣言された型にプロトコル準拠を追加できます。拡張機能では、採用したプロトコル要件のすべてを実装しなければなりません。型がすでにすべての要件を実装している場合は、拡張機能の宣言の本体を空のまま残すことができます。
デフォルトでは、プロトコルに準拠する型は、プロトコルで宣言されたすべてのプロパティ、メソッド、およびサブスクリプトを実装しなければなりません。つまり、準拠する型によるそれらの実装はオプションであることを指定するには、optional の宣言修飾子でこれらのプロトコルメンバ宣言をマークできます。 optional の修飾子は、objc 属性でマークされているメンバにのみ適用でき、objc 属性でマークされたプロトコルメンバにのみ適用できます。その結果、クラス型だけが、optional メンバの要件を含むプロトコルに準拠し、採用できます。optional の宣言修飾子を使用する方法の詳細、また optional のプロトコルメンバにアクセスする方法ー例えば、準拠型がそれらを実装しているかどうかわからないときは、Optional のプロトコル要件 を参照してください。
列挙型の case は、型メンバのプロトコル要件を満たすことができます。具体的には、値が関連していない列挙型の case は、Self 型の取得専用の型変数のプロトコル要件を満たし、また値が関連している列挙型の case は、そのパラメータと引数ラベルが case の関連した値と一致する Self を返す関数のプロトコル要件を満たします。例えば:
クラス型へのプロトコルの採用を制限するだけなら、コロンの後に 継承されたプロトコル のリスト内に AnyObject プロトコルを含めます。たとえば、以下のプロトコルは、クラス型によってのみ採用できます。
AnyObject 要件でマークされたプロトコルから継承する全てのプロトコルは、同様に、クラス型によってのみ採用することができます。
プロトコルは、名前の付いた型であり、型としてのプロトコル で説明したように、それらは、他の名前の付いた型としてコード内のすべての同じ場所に表示することができます。しかし、プロトコルは実際にはそれらが指定した要件の実装を提供しないので、プロトコルのインスタンスを構築することはできません。
デリゲート で説明したように、プロトコルを使用して、クラスまたは構造体のデリゲートが実装すべきメソッドを宣言することができます。
プロトコルに準拠した型は、プロトコル宣言の本体内に プロトコルプロパティ宣言 を含めることで、プロパティを実装しなければならないことを宣言します。プロトコルプロパティ宣言は変数宣言の特別な形式です:
var <#property name#> : <#type#> { get set }
他のプロトコルメンバ宣言と同様に、これらのプロパティ宣言は、プロトコルに準拠する型用のゲッタとセッタの要件だけを宣言します。その結果、それが宣言されているプロトコルで直接ゲッタとセッタを実装しません。
ゲッタとセッタの要件は、準拠する型によってさまざまな方法で満たされます。プロパティ宣言が、get と set キーワードの両方を含んでいる場合、準拠する型は読み書き可能 (つまり、ゲッタとセッタの両方を実装するもの) な格納された変数プロパティまたは計算されたプロパティでそれを実装できます。しかし、そのプロパティ宣言は、定数プロパティや読み取り専用の計算されたプロパティとしては実装できません。プロパティ宣言が get キーワードのみを含む場合は、プロパティの任意の種類として実装できます。プロトコルのプロパティの要件を実装する型を準拠する例については、プロパティの要件 を参照してください。
プロトコル宣言で型プロパティ要件を宣言するには、static キーワードでプロパティ宣言をマークします。プロトコルに準拠する構造体と列挙型は、static キーワードを使用してプロパティを宣言し、プロトコルに準拠するクラスは、static または class キーワードを使用してプロパティを宣言します。構造体、列挙型、またはクラスにプロトコル準拠を追加する拡張機能は、拡張する型が使用するのと同じキーワードを使用します。型プロパティ要件のデフォルトの実装を提供する拡張機能は、static キーワードを使用します。
変数の宣言 も参照してください。
プロトコルは、それに準拠した型が、プロトコル宣言の本体内にプロトコルメソッド宣言を含めることで、メソッドを実装しなければならないことを宣言します。プロトコルメソッド宣言は、2つの例外を除いて関数宣言と同じ形式です。それらは、関数本体を含みませんし、関数宣言の一部として、デフォルトのパラメータ値を提供することは全くできません。プロトコルのメソッドの要件を実装する準拠型の例については、メソッドの要件 を参照してください。
プロトコル宣言内でクラスまたは静的メソッドの要件を宣言するには、static 宣言修飾子でメソッド宣言をマークして下さい。プロトコルに準拠する構造体と列挙型は、static キーワードでメソッドを宣言し、プロトコルに準拠するクラスは、static または class キーワードでメソッドを宣言します。プロトコルの準拠性を構造体、列挙型、またはクラスに追加する拡張機能は、拡張する型が使用するのと同じキーワードを使用します。型メソッド要件のデフォルトの実装を提供する拡張機能では、static キーワードを使用します。
関数の宣言 も参照してください。
プロトコルは、それに準拠した型が、プロトコル宣言の本体内にプロトコルイニシャライザ宣言を含めることで、イニシャライザを実装しなければならないことを宣言します。プロトコルイニシャライザ宣言は、イニシャライザの本体を含まない事を除いて、イニシャライザの宣言と同じ形式を持っています。
準拠する型は、失敗できないイニシャライザまたは init! の失敗可能なイニシャライザを実装することで、失敗できないプロトコルイニシャライザの要件を満たすことができます。準拠する型は、イニシャライザのいずれかの種類を実装することで、失敗可能なプロトコルイニシャライザの要件を満たすことができます。
クラスが、プロトコルのイニシャライザ要件を満たすためにイニシャライザを実装する場合は、クラスがまだ final 宣言修飾子でマークされていなければ、イニシャライザは、required 宣言修飾子でマークされなければなりません。
イニシャライザ宣言 も参照してください。
プロトコルは、それに準拠した型が、プロトコル宣言の本体内にプロトコルサブスクリプト宣言を含めることで、サブスクリプトを実装しなければならないことを宣言します。プロトコルサブスクリプト宣言は、サブスクリプト宣言の特殊な形式です。
subscript ( <#parameters#> ) -> <#return type#> { get set }
サブスクリプト宣言は、プロトコルに準拠する型の最小限のゲッタとセッタの実装要件のみを宣言します。サブスクリプト宣言が get および set キーワード両方を含んでいる場合は、準拠型はゲッタとセッタ節両方を実装しなければなりません。サブスクリプト宣言が get キーワードのみを含んでいる場合は、準拠型は 少なくとも ゲッタ節を実装しなければならず、オプションでセッタ節を実装できます。
プロトコル宣言で静的なサブスクリプト要件を宣言するには、static 宣言修飾子を使用してサブスクリプト宣言をマークします。プロトコルに準拠する構造体と列挙型は、static キーワードでサブスクリプトを宣言し、プロトコルに準拠するクラスは、static または class キーワードでサブスクリプトを宣言します。構造体、列挙型、またはクラスにプロトコル準拠を追加する拡張機能は、拡張する型が使用するのと同じキーワードを使用します。静的サブスクリプト要件のデフォルト実装を提供する拡張機能は、static キーワードを使用します。
サブスクリプト宣言 も参照してください。
プロトコルは、associatedtype キーワードを使用して、関連する型を宣言します。関連する型は、プロトコル宣言の一部として使用されている型エイリアスを提供します。関連する型は、汎用パラメータ節の型パラメータに似ていますが、それらが宣言されているプロトコルでの Self に関連しています。その文脈では、Self はプロトコルに準拠する、最終的な型を参照します。詳細および例については、関連型 を参照してください。
関連型を再宣言することなく、プロトコル宣言で汎用の where 節を使用して、別のプロトコルから継承した関連型に制約を追加して下さい。たとえば、以下の SubProtocol の宣言は同等です。
型エイリアス宣言 も参照してください。
イニシャライザ宣言 はプログラムに、クラス、構造体、または列挙型のイニシャライザを導入します。イニシャライザ宣言は、init キーワードを使用して宣言し、2つの基本的な形式があります。
構造体、列挙型、およびクラス型は、いくつでもイニシャライザを持てますが、クラスイニシャライザのための規則と関連した動作は異なっています。構造体や列挙型とは異なり、クラスには2種類のイニシャライザがあります:指定イニシャライザとコンビニエンス・イニシャライザです。詳しくは 初期化 を参照して下さい。
以下の形式は、構造体、列挙型のイニシャライザ、およびクラスの指定イニシャライザを宣言しています。
init ( <#parameters#> ) {
<#statements#>
}
クラスの指定イニシャライザは、直接クラスのすべてのプロパティを初期化します。それは、同じクラスの他のイニシャライザを呼び出すことは全くできず、クラスがスーパークラスを持つ場合、スーパークラスの指定イニシャライザのいずれか一つを呼び出さなければなりません。クラスがそのスーパークラスからいくつかプロパティを継承する場合、これらのプロパティのいずれかが現在のクラスで設定されまたは変更される前に、スーパークラスの指定イニシャライザの一つが呼び出されなければなりません。
指定イニシャライザは、クラス宣言の文脈の中でのみ宣言できるため、拡張機能の宣言を使用してクラスに追加はできません。
構造体や列挙型におけるイニシャライザは、初期化プロセスの一部またはすべてをデリゲートする他の、宣言されたイニシャライザを呼び出すことができます。
クラスのコンビニエンスイニシャライザを宣言するには、convenience 宣言修飾子でイニシャライザ宣言をマークして下さい。
convenience init ( <#parameters#> ) {
<#statements#>
}
コンビニエンスイニシャライザは、他のコンビニエンスイニシャライザまたはクラスの指定イニシャライザのいずれか一つに、初期化プロセスをデリゲートすることができます。つまり、初期化プロセスは、最終的には、クラスのプロパティを初期化する指定イニシャライザへの呼び出しで終了しなければなりません。コンビニエンスイニシャライザは、スーパークラスのイニシャライザを呼び出すことはできません。
required 宣言修飾子で指定イニシャライザとコンビニエンスイニシャライザをマークして、すべてのサブクラスでイニシャライザを実装することを要求できます。そのイニシャライザのサブクラスの実装も、 required 宣言修飾子でマークされなければなりません。
デフォルトでは、スーパークラスで宣言されたイニシャライザはサブクラスによっては継承されません。つまり、サブクラスがデフォルト値で、その格納されたすべてのプロパティを初期化し、独自のイニシャライザを全く定義していない場合には、スーパークラスのすべてのイニシャライザを継承します。サブクラスがスーパークラスの指定イニシャライザのすべてをオーバーライドする場合、それはスーパークラスのコンビニエンスイニシャライザを継承します。
メソッド、プロパティ、およびサブスクリプトと同様に、override 宣言修飾子で、オーバーライドされた指定イニシャライザをマークする必要があります。
関数やメソッドと全く同様に、イニシャライザはエラーを throw または rethrow できます。また、関数やメソッドと全く同様に、イニシャライザのパラメータの後に throws または rethrows キーワードを使用して、適切な動作を示して下さい。同様に、イニシャライザは非同期にすることができ、これを示すには async キーワードを使用します。
さまざまな型宣言のイニシャライザの例を参照するには、初期化 を参照してください。
失敗可能イニシャライザ (failable initializer) は、optional のインスタンスまたはイニシャライザが宣言されている型の暗黙的に開封された optional のインスタンスを生成するイニシャライザの一つの型です。その結果、失敗可能イニシャライザは、初期化に失敗した事を示すため nil を返すことができます。
optional のインスタンスを生成する失敗可能イニシャライザを宣言するには、イニシャライザの宣言の init キーワードに疑問符を追加 (init?) します。暗黙的に開封された optional のインスタンスを生成する失敗可能イニシャライザを宣言するには、代わりに感嘆符を追加 (init!) します。以下の例は、構造体の optional のインスタンスを生成する init? の失敗可能イニシャライザの例を示しています。
結果が optional である事に対処しなければならないことを除いては、失敗できないイニシャライザを呼び出すのと同じ方法で init? の失敗可能イニシャライザを呼び出せます。
失敗可能イニシャライザは、イニシャライザの本体の実装の任意の時点で nil を返すことができます。
失敗可能イニシャライザはどのような種類のイニシャライザにもデリゲートできます。失敗できないイニシャライザは、他の失敗できないイニシャライザまたは init! の失敗可能イニシャライザにデリゲートできます。失敗できないイニシャライザは、スーパークラスのイニシャライザの結果を強制開封することにより、init? の失敗可能イニシャライザにデリゲートできます–例えば、super.ini( )! と書くことによって。
初期化失敗はイニシャライザのデリゲートを介して伝播します。具体的には、失敗可能イニシャライザが、失敗して nil を返すイニシャライザにデリゲートする場合、デリゲートされたイニシャライザも失敗し、暗黙的に nil を返します。失敗できないイニシャライザが失敗して nil を返す init! の失敗可能イニシャライザにデリゲートすると、実行時エラーが発生します (! 演算子を使用して、nil 値を持つ optional を開封した場合のように)。
失敗可能指定イニシャライザは、指定イニシャライザのどの種類によってもサブクラス内でオーバーライドできます。失敗できない指定イニシャライザは、失敗できない指定イニシャライザによってのみサブクラス内でオーバーライドできます。
詳細と失敗可能イニシャライザの例を見るには、失敗可能イニシャライザ を参照してください。
デイニシャライザ宣言 はクラス型のためのデイニシャライザを宣言します。デイニシャライザはパラメータを全くとらず、以下の形式です:
deinit {
<#statements#>
}
クラスオブジェクトへの参照がもはやない場合に、クラスオブジェクトが割り当て解除される直前にデイニシャライザは自動的に呼び出されます。デイニシャライザは、クラス宣言の本体内でのみ宣言できますが、クラスの拡張機能の中では宣言できず、各クラスは最大一つデイニシャライザを持つことができます。
サブクラスは、そのスーパークラスのデイニシャライザを継承し、サブクラスオブジェクトが割り当て解除される直前に暗黙的に呼び出されます。サブクラスオブジェクトは、その継承連鎖のすべてのデイニシャライザの実行が終了するまで、割り当て解除されません。
デイニシャライザは直接呼び出されません。
クラス宣言内でデイニシャライザを使用する方法の例については、デイニシャライザ を参照してください。
拡張機能の宣言 では、既存の型の動作を拡張できます。拡張機能の宣言は、extension キーワードを使用して宣言し、以下のような形式です:
extension <#type name#> where <#requirements#> {
<#declarations#>
}
拡張機能の宣言の本体は、ゼロ個以上の 宣言 を含んでいます。これらの 宣言 は、計算されたプロパティ、計算された型プロパティ、インスタンスメソッド、型メソッド、イニシャライザ、サブスクリプト宣言、さらにはクラス、構造体、および列挙型宣言を含めることができます。拡張機能の宣言にはデイニシャライザまたはプロトコル宣言、格納されたプロパティ、プロパティ監視者、または他の拡張機能の宣言を含めることはできません。プロトコル機能拡張内の宣言には final でマークをすることはできません。拡張機能の議論や宣言の様々な種類を含むいくつかの例については、拡張機能 を参照してください。
型名 がクラス、構造体または列挙型の場合、拡張機能はその型を拡張します。型名 がプロトコル型の場合、拡張機能はそのプロトコルに準拠するすべての型を拡張します。
汎用型を拡張する拡張機能の宣言または関連する型を持つプロトコルには、要件 を含めることができます。拡張型または拡張プロトコルに準拠する型のインスタンスが 要件 を満たす場合、そのインスタンスは宣言で指定された動作を取得します。
拡張機能の宣言はイニシャライザ宣言を含むことができます。つまり、拡張しようとする型が別のモジュールで定義されている場合、イニシャライザ宣言は、その型のメンバが正しく初期化されるように、そのモジュールですでに定義されているイニシャライザにデリゲートしなければなりません。
既存の型のプロパティ、メソッド、およびイニシャライザはその型の拡張機能内でオーバーライドすることはできません。
拡張機能の宣言は、採用されているプロトコル を指定することによって、既存のクラス、構造体、または列挙型にプロトコル準拠を追加できます:
extension <#type name#> : <#adopted protocols#> where <#requirements#> {
<#declarations#>
}
拡張機能の宣言では既存のクラスにクラスの継承を追加できないため、型名 とコロンの後にプロトコルのリストのみを指定できます。
条件付きでプロトコルに準拠するように汎用型を拡張して、特定の要件が満たされた場合にのみその型のインスタンスがプロトコルに準拠するようにできます。拡張機能の宣言に 要件 を含めることによって、プロトコルに条件付き準拠を追加して下さい。
いくつかの汎用の文脈 (context) では、条件付き準拠からプロトコルへの動作を得る型は、常にそのプロトコルの要件の特殊な実装を使用するとは限りません。この動作を説明するために、以下の例では 2 つのプロトコルと、条件付きで両方のプロトコルに準拠する汎用型を定義しています。
Pair 構造体は、その汎用型がそれぞれ Loggable または TitledLoggable に準拠している場合は常に Loggable および TitledLoggable に準拠しています。以下の例では、oneAndTwo は Pair<String> のインスタンスであり、これは String が TitledLoggable に準拠しているため、TitledLoggable に準拠しています。log( ) メソッドが oneAndTwo で直接呼び出されると、タイトルの文字列を含む特殊なバージョンが使用されます。
ただし、oneAndTwo が汎用の文脈で使用されたり、Loggable プロトコルのインスタンスとして使用される場合は、特別なバージョンは使用されません。Swift は、Pair が Loggable に準拠するために必要な最小限の要件のみを調べることによって、呼び出す log( ) の実装を選択します。このため、Loggable プロトコルで提供されているデフォルトの実装が代わりに使用されます。
doSomething(_:) に渡されたインスタンスで log( ) が呼び出されると、カスタマイズされたタイトルはログに記録された文字列から省略されます。
具象的な型は、特定のプロトコルに一度だけ準拠できます。Swift は冗長なプロトコル準拠性をエラーとしてマークします。2 種類の状況でこの種のエラーに遭遇する可能性があります。最初の状況は、同じプロトコルに複数回明示的に準拠しているが、要件が異なる場合です。2 番目の状況は、暗黙的に同じプロトコルから複数回継承する場合です。これらの状況については、以下のセクションで説明します。
拡張機能の要件が相互に排他的であっても、具象的な型の複数の拡張機能は、同じプロトコルへの準拠性を追加することはできません。この制限は、以下の例で説明します。2 つの拡張機能の宣言は、Serializable プロトコルに条件付き準拠を追加しようとします。1 つは Int 要素を持つ配列用、もう 1 つは String 要素を持つ配列用です。
複数の具体的な型に基づく条件付き準拠を追加する必要がある場合は、各型が準拠できる新しいプロトコルを作成し、条件付き準拠を宣言するときの要件としてそのプロトコルを使用します。
具体的な型が条件付きでプロトコルに準拠している場合、その型は暗黙のうちに同じ要件を持つ親プロトコルに準拠しています。
単一の親から継承する 2 つのプロトコルに条件付きで準拠する型が必要な場合は、親プロトコルへの準拠を明示的に宣言してください。これにより、異なる要件で 2 回親プロトコルに暗黙的に準拠することが回避されます。
以下の例では、TitledLoggable プロトコルと新しい MarkedLoggable プロトコルの両方に条件付きで準拠することを宣言するときに競合を避けるために、Array から Loggable への条件付き準拠を明示的に宣言しています。
Loggable への条件付き準拠を明示的に宣言する拡張機能がなければ、他の Array の拡張機能は暗黙的にこれらの宣言を作成し、結果としてエラーになります。
サブスクリプト 宣言では、特定の型のオブジェクトのサブスクリプトサポートを追加し、コレクション、リスト、またはシーケンス内の要素にアクセスするための便利な構文を提供するために典型的に使用できるようにします。サブスクリプト宣言は subscript キーワードを使用して宣言し、以下のような形式です:
subscript ( <#parameters#> ) -> <#return type#> {
get {
<#statements#>
}
set( <#setter name#> ) {
<#statements#>
}
}
サブスクリプト宣言は、クラス、構造体、列挙型、拡張機能、またはプロトコル宣言の文脈にのみ現れます。
パラメータ は、サブスクリプト式に対応する型の要素にアクセスするために使用される1つ以上のインデックスを指定します (例えば、式 object[i] での i)。要素にアクセスするために使用されるインデックスは任意の型のものですが、それぞれのパラメータには、各インデックスの型を指定するための型注釈を含めなければなりません。戻り値の型 は、アクセスされている要素の型を指定します。
計算されたプロパティと同様に、サブスクリプト宣言は、アクセスした要素の値を読み書きするサポートをします。ゲッタは、値を読み出すために使用され、セッタは、値を書き込むために使用されます。セッタ節はオプションで、ゲッタだけが必要なときには、両方の節を省略して、要求された値を直接単に返せます。つまり、セッタ節を提供する場合、ゲッタ節も提供しなければなりません。
セッタ名 とそれを囲む括弧はオプションです。セッタ名を提供する場合は、セッタへのパラメータの名前としてそれは使用されます。セッタ名を提供しない場合は、セッタへのデフォルトのパラメータ名は value です。セッタへのパラメータ型は、戻り値の型 と同じです。
パラメータ や 戻り値の型 が、オーバーロードしたものと異なる限り、それが宣言されている型でのサブスクリプト宣言をオーバーロードできます。また、スーパークラスから継承されたサブスクリプト宣言をオーバーライドする事もできます。これを行う時は、override 宣言修飾子でオーバーライドされたサブスクリプト宣言をマークしなければなりません。
サブスクリプトパラメータは、2 つの例外を除いて、関数パラメータと同じ規則に従います。デフォルトでは、サブスクリプトで使用されるパラメータには、関数、メソッド、およびイニシャライザとは異なり、引数ラベルはありません。ただし、関数、メソッド、およびイニシャライザが使用するのと同じ構文を使用して、明示的な引数ラベルを提供できます。また、サブスクリプトには in-out パラメータを指定できません。パラメータの特殊な種類 で説明した構文を使用して、サブスクリプトパラメータにデフォルト値を設定できます。
プロトコルサブスクリプト宣言 で説明したように、プロトコル宣言の文脈でサブスクリプトを宣言する事もできます。
サブスクリプト宣言の例の参照と詳細については、サブスクリプト を参照してください。
型のインスタンスによってではなく、型によって公開されるサブスクリプトを宣言するには、サブスクリプト宣言を static 宣言修飾子でマークします。クラスは、スーパークラスの実装をサブクラスがオーバーライドするのを許可する代わりに class 宣言修飾子で型の計算されたプロパティをマークできます。クラス宣言では、static キーワードは、class と final の宣言修飾子の両方で宣言をマークするのと同じ効果があります。
マクロの宣言 は新しいマクロを導入します。マクロ宣言は macro のキーワードで始まり、以下の形式になります。
マクロの実装 (macro implementation) は別のマクロであり、このマクロの展開を実行するコードの場所を示します。マクロ展開を実行するコードは別の Swift プログラムであり、SwiftSyntax モジュールを使用して Swift コードを操作します。マクロの実装を含む型の名前と、その型を含むモジュールの名前を渡して、Swift 標準ライブラリから externalMacro(module:type:) マクロを呼び出します。
マクロは、関数で使用されるのと同じモデルに従ってオーバーロードできます。マクロの宣言はファイルのスコープでのみ表示されます。
Swift のマクロの概要については、マクロ を参照してください。
演算子の宣言 は、プログラムに新しい挿入辞、接頭辞、または接尾辞演算子を導入し、operator キーワードを使用して宣言されます。
挿入辞、接頭辞および接尾辞の、3つの異なる定着演算子を宣言できます。演算子の 定着性 は、そのオペランドへの演算子の相対的な位置を指定します。
演算子の宣言の3つの基本的な形式は、それぞれの定着性に一つずつあります。演算子の定着性は、operator キーワードの前に infix,prefix または postfix 宣言修飾子で演算子の宣言をマークすることによって指定されます。各形式では、演算子の名前は、演算子 で定義された演算子の文字のみを含めることができます。
以下の形式で、新しい挿入辞演算子を宣言します。
infix operator <#operator name#>: <#precedence group#>
挿入辞演算子 は、式 1 + 2 でおなじみの加算演算子 (+) のような、2つのオペランドの間に書かれる二項演算子です。
挿入辞演算子は、オプションで優先順位グループを指定できます。演算子の優先順位グループを省略すると、Swift はデフォルトの優先順位グループ DefaultPrecedence を使用します。これは、TernaryPrecedence よりも 1 つだけ高い優先順位を指定します。詳細については、優先順位グループ宣言 を参照してください。
以下の形式で、新しい接頭辞演算子を宣言します。
prefix operator <#operator name#>
接頭辞演算子 は、式 !a での接頭辞論理 NOT 演算子 (!) のような、そのオペランドの直前に書かれた単項演算子です。
接頭辞演算子の宣言では、優先順位レベルは指定されません。接頭辞演算子は非結合性です。
以下の形式で、新しい接尾辞演算子を宣言します。
postfix operator <#operator name#>
接尾辞演算子 は、式 a! での接尾辞強制開封演算子 (!) のような、そのオペランドの直後に書かれる単項演算子です。
接頭辞演算子と同様に、接尾辞演算子宣言は優先順位レベルを指定しません。接尾辞演算子は非結合性です。
新しい演算子を宣言した後は、その演算子と同じ名前の静的メソッドを宣言してそれを実装します。静的メソッドは、演算子が引数として取る値の 1 つの型のメンバです。たとえば、Double に Int を乗算する演算子は、Double または Int 構造体のいずれかに静的メソッドとして実装されます。接頭辞または接尾辞演算子を実装している場合は、そのメソッド宣言に対応する prefix または postfix 宣言修飾子をも付けてマークしなければなりません。新しい演算子を作成して実装する方法の例については、カスタム演算子 を参照してください。
優先順位グループ宣言 では、挿入辞演算子の優先順位をプログラムに追加するための新しいグループを導入します。演算子の優先順位は、グループ化する括弧のない場合、演算子がそのオペランドにどれくらい緊密に結合するかを指定します。
優先順位グループ宣言の形式は以下のとおりです。
precedencegroup <#precedence group name#> {
higherThan: <#lower group names#>
lowerThan: <#higher group names#>
associativity: <#associativity#>
assignment: <#assignment#>
}
低い順位のグループ名 (lower group names) および 高い順位のグループ名 (higher group names) のリストは、新しい優先順位グループと既存の優先順位グループとの関係を指定します。lowerThan の優先順位のグループ属性は、現在のモジュールの外部で宣言された優先順位グループを参照するためにのみ使用できます。2つの演算子が式 2 + 3 * 5 のようにそのオペランドで互いに競合する場合、相対的に優先順位の高い演算子がそのオペランドにより強く結びつきます。
Swift は、標準ライブラリによって提供される演算子と一緒にするために多数の優先順位グループを定義しています。たとえば、加算 (+) および減算 (-) 演算子は AdditionPrecedence グループに属し、乗算 (*) および除算 (/) 演算子は MultiplicationPrecedence グループに属します。Swift 標準ライブラリが提供する優先順位グループの完全なリストについては、演算子の宣言 を参照してください。
演算子の 結合性 は、グループ化する括弧が存在しない場合に、同じ優先順位レベルを持つ演算子のシーケンスをどのようにグループ化するかを指定します。文脈依存のキーワードの1つ、left、right または none のいずれかを書くことによって、演算子の結合性を指定します。結合性を省略すると、デフォルトは none になります。左結合グループである演算子は左から右へグループ化されます。たとえば、減算演算子 (-) は左結合性であるため、式 4 - 5 - 6 は (4 - 5) - 6 とグループ化され、-7 と評価されます。右結合グループである右から左の演算子、および none の結合性で指定された演算子はまったく結合しません。同じ優先順位レベルの非結合演算子は、互いに隣接して表示することはできません。たとえば、< 演算子の結合性は none です。これは、1 < 2 < 3 は有効な式ではないことを意味します。
優先順位グループの 代入 は、optional の連鎖を含む演算で使用される場合、演算子の優先順位を指定します。true に設定すると、対応する優先順位グループの演算子は、Swift 標準ライブラリからの代入演算子として、optional の連鎖中に同じグループ化規則を使用します。それ以外の場合、false に設定するか省略すると、優先順位グループの演算子は、代入を実行しない演算子と同じ optional の連鎖規則に従います。
宣言修飾子 は、キーワードまたは宣言の動作や意味を変更する文脈に敏感なキーワードです。適切なキーワードまたは宣言の属性 (もしあれば) の間の文脈に敏感なキーワード及び宣言を導入するキーワードを書くことによって宣言修飾子を指定して下さい。
class
この修飾子をクラスのメンバに適用して、そのメンバがクラスのインスタンスのメンバではなく、クラス自体のメンバであることを示します。この修飾子を持ち、final 修飾子を持たないスーパークラスのメンバは、サブクラスでオーバーライドできます。
dynamic
Objective-C で表されるクラスの任意のメンバにこの修飾子を適用します。dynamic 修飾子でメンバ宣言をマークすると、そのメンバへのアクセスは常に Objective-C の実行時環境を使用して動的に送出されます。そのメンバへのアクセスは、コンパイラによって全くインライン化されず、仮想化されません。
dynamic 修飾子でマークされる宣言は、Objective-C 実行時環境を使用して送出されるので、それらは objc 属性でマークされなければなりません。
final
クラスまたはクラスのプロパティ、メソッド、またはサブスクリプトメンバにこの修飾子を適用して下さい。これは、クラスがサブクラス化できないことを示すためにクラスに適用されます。クラスのメンバは全てのサブクラスでオーバーライドできないことを示すために、クラスのプロパティ、メソッド、またはサブスクリプトにこれは適用されます。final 属性の使用例については、オーバーライドの防止 を参照してください。
lazy
プロパティの初期値が計算され、多くとも1回、プロパティに最初にアクセスしたときに格納されることを示すために、クラスまたは構造体の格納された変数プロパティに、この修飾子を適用して下さい。lazy 修飾子を使用する方法の例については、遅延した格納されたプロパティ を参照してください。
optional
準拠する型はそれらのメンバを実装するのに必須ではないことを示すために、プロトコルのプロパティ、メソッド、またはサブスクリプトメンバに、この修飾子を適用します。
objc 属性でマークされているプロトコルにのみ、optional 修飾子を適用できます。その結果、クラス型だけが、optional のメンバ要件を含むプロトコルを採用し、準拠できます。optional 修飾子を使用する詳しい方法と optional プロトコルメンバにアクセスする方法のガイドについては、例えば、準拠型がそれらを実装しているかどうかわからない時は、Optional のプロトコル要件 を参照してください。
required
すべてのサブクラスが、そのイニシャライザを実装しなければならないことを示すために、クラスの指定イニシャライザ、またはコンビニエンス・イニシャライザに、この修飾子を適用します。そのイニシャライザのサブクラスの実装も、required 修飾子でマークされなければなりません。
static
この修飾子を構造体、クラス、列挙型、またはプロトコルのメンバに適用して、メンバがその型のインスタンスのメンバではなく、その型のメンバであることを示します。クラス宣言のスコープでは、メンバ宣言に static 修飾子を記述すると、そのメンバ宣言に class 修飾子と final 修飾子を記述するのと同じ効果があります。ただし、クラスの定数型プロパティは例外です。class または final をこれらの宣言で記述できないため、static は、通常の、クラスでない意味があります。
unowned
この修飾子を、格納された変数、定数、または格納されたプロパティに適用して、変数またはプロパティがその値として格納されたオブジェクトへの所有されていない参照を持つことを示します。オブジェクトが割り当てを解除された後に変数またはプロパティにアクセスしようとすると、実行時エラーが発生します。弱い参照と同様に、プロパティ型または値型はクラス型でなければなりません。弱い参照とは異なり、型は optional ではありません。unowned 修飾子の例と詳細については、所有されていない参照 を参照してください。
unowned(safe)
unowned の明示的な綴り。
unowned(unsafe)
この修飾子を、格納された変数、定数、または格納されたプロパティに適用して、変数またはプロパティがその値として格納されたオブジェクトへの所有されていない参照を持つことを示します。オブジェクトが割り当てを解除された後に変数またはプロパティにアクセスしようとすると、オブジェクトが存在していた場所のメモリにアクセスします。これはメモリが安全でない操作です。弱い参照と同様に、プロパティ型または値型はクラス型でなければなりません。弱い参照とは異なり、型は optional ではありません。 unowned 修飾子の例と詳細については、所有されていない参照 を参照してください。
weak
この修飾子を、格納された変数または格納された変数プロパティに適用して、変数またはプロパティがその値として格納されたオブジェクトへの弱い参照を持つことを示します。変数型またはプロパティ型は、optional のクラス型でなければなりません。オブジェクトが割り当てを解除された後に変数またはプロパティにアクセスすると、その値は nil になります。weak 修飾子の例と詳細については、弱い参照 を参照してください。
Swift は、アクセス制御に五つのレベルを提供します:open,public,internal,file private, および private です。宣言のアクセスレベルを指定するには、以下のアクセス·レベルの修飾子の一つで宣言をマークできます。アクセス制御は、アクセス制御 で詳細に議論しています。
open
この修飾子を宣言に適用して、宣言と同じモジュール内のコードで宣言がアクセスでき、またサブクラス化できることを示します。open のアクセスレベル修飾子でマークされた宣言は、その宣言を含むモジュールを import するモジュール内のコードによってもアクセスでき、またサブクラス化することもできます。
public
この修飾子を宣言に適用して、宣言と同じモジュール内のコードで宣言がアクセスでき、またサブクラス化できることを示します。public のアクセスレベル修飾子でマークされた宣言は、その宣言を含むモジュールを import するモジュール内のコードによってもアクセスできます (しかしサブクラス化はできません)。
package
この修飾子を宣言に適用すると、宣言には宣言と同じパッケージ内のコードからのみアクセスできることを示します。パッケージとは、あなたの使用しているビルドシステムで定義するコード配布の単位です。ビルドシステムは、コードをコンパイルするときに、Swift コンパイラに -package-name フラグを渡してパッケージ名を指定します。ビルドシステムが 2 つのモジュールをビルドするときに同じパッケージ名を指定すると、それらのモジュールは同じパッケージの一部になります。
internal
この修飾子を宣言に適用して、宣言と同じモジュール内のコードでのみ宣言がアクセスできることを示します。デフォルトでは、ほとんどの宣言は暗黙のうちに internal のアクセスレベル修飾子でマークされています。
fileprivate
この修飾子を宣言に適用して、宣言と同じソースファイル内のコードによってのみ宣言がアクセスできることを示します。
private
この修飾子を宣言に適用して、宣言が直接に取り囲むスコープ内のコードによってのみ宣言がアクセスできることを示します。
アクセス制御の目的で、同じファイル内の同じ型への拡張機能がアクセス制御スコープを共有します。拡張された型が同じファイル内にもある場合、型のアクセス制御スコープも共有されます。型の宣言で宣言された private メンバは、拡張機能からアクセスでき、ある拡張機能で宣言された private メンバは、他の拡張機能と型宣言からアクセスできます。
上記の各アクセスレベルの修飾子は、必要に応じて、括弧で囲まれた set キーワードで構成された一つの引数 (例えば、private(set) )を受け付けます。ゲッタとセッタ で説明したように、変数またはサブスクリプト自体のアクセスレベル以下の変数またはサブスクリプトのセッタのアクセスレベルを指定する場合、アクセスレベル修飾子のこの形式を使用します。