Swift 6.2 日本語化計画 : Swift 6.2
拡張機能
拡張機能 は、既存のクラス、構造体、列挙型、またはプロトコル型に新しい機能を追加します。これは、(逆行的モデリング として知られている) 元のソースコードへのアクセス権を持っていない型を拡張する機能を含んでいます。拡張機能は、Objective-C のカテゴリに似ています。(Objective-C のカテゴリとは異なり、Swift の拡張機能には名前がありません。)
Swift の拡張機能は以下のことができます:
Swift では、その要件の実装を提供し、準拠する型を活用できる機能を追加するためのプロトコルを拡張することもできます。詳細については、プロトコル拡張機能 を参照してください。
extension キーワードを使用して拡張機能を宣言します。
拡張機能は、1つ以上のプロトコルを採用するために、既存の型を拡張できます。プロトコルの準拠を追加するには、クラスまたは構造体を書くのと同じ方法でプロトコル名を記述して下さい。
このようなプロトコル準拠の追加は 拡張機能を持つプロトコル準拠の追加 で説明されています。
汎用型の拡張 で説明したように、拡張機能を使用して、既存の汎用型を拡張することができます。汎用の Where 句を含む拡張機能 で説明したように、汎用型を拡張して条件付きで機能を追加することもできます。
拡張機能は、既存の型に、計算されたインスタンスプロパティと計算された型プロパティを追加できます。以下の例では、距離の単位を扱うための基本的なサポートを提供するために、Swift の組み込みの Double 型に5つの計算されたインスタンスプロパティを追加します。
これらの計算されたプロパティは、長さの特定の単位として Double 値が考えられるべきだと表します。それらは計算されたプロパティとして実装されていますが、これらのプロパティの名前は、距離の変換を実行するために、そのリテラル値を使用する方法として、ドット構文を持つ浮動小数点リテラル値に追加できます。
この例では、1.0 の Double 値は "1メートル" を表すと考えられます。これは、m の計算されたプロパティが self を返し、式 1.m が 1.0 の Double 値を計算するとみなされるためです。
他の単位はメートルで測定した値として表現するためにいくつかの変換が必要です。1 キロメートルは、1000 メートルと同じで、km の計算されたプロパティはメートルで表した数値に変換するため 1_000.00 の値を乗算します。同様に、1メートルは 3.28084 フィートであり、フィートをメートルに変換するには ft の計算されたプロパティは 3.28084 で基本的な Double 値を除算します。
これらのプロパティは、読み取り専用の計算されたプロパティで、したがってそれらは簡潔にするために、get キーワードなしで表わされています。それらの戻り値は Double 型であり、Double が受け入れられる場所ならどこでも数学的計算の中で使用できます:
拡張機能は、既存の型に新しいイニシャライザを追加できます。これは、イニシャライザ・パラメータとして独自のカスタム型を受け入れるように他の型を拡張する事を可能にし、または型のオリジナルの実装の一部としては含まれていなかった追加の初期化オプションを提供できます。
拡張機能は、クラスに新しいコンビニエンス・イニシャライザを追加できますが、クラスに新しい指定イニシャライザまたはデイニシャライザの追加はできません。指定イニシャライザとデイニシャライザは、常にオリジナルのクラスの実装によって提供されなければなりません。
拡張機能を使用して、その格納されたプロパティすべてにデフォルト値を提供する値型にイニシャライザを追加できますが、カスタムイニシャライザを定義しないし、その拡張機能のイニシャライザ内からその値型のデフォルトのイニシャライザおよびメンバ化イニシャライザを呼び出すことができます。値型のイニシャライザデリゲート で説明したように、イニシャライザを値型のオリジナルの実装の一部として記述した場合は、これはあてはまりません。
拡張機能を使用して別のモジュール内で宣言された構造体にイニシャライザを追加した場合、新しいイニシャライザは定義しているモジュールからイニシャライザを呼び出すまで self にアクセスできません。
以下の例では、幾何学的な長方形を表すためにカスタムの Rect 構造体を定義しています。また、この例では、Size と Point と言う、2つのサポートする構造体も定義しており、どちらも全てのプロパティに 0.0 のデフォルト値を提供しています。
Rect 構造体は、そのすべてのプロパティのデフォルト値を提供するので、それは デフォルトのイニシャライザ で説明したように、自動的にデフォルトのイニシャライザとメンバ化イニシャライザを受け取ります。これらのイニシャライザは、新しい Rect インスタンスを作成するために使用できます:
特定の中心点とサイズを取る追加のイニシャライザを提供するために、Rect 構造体を拡張できます。
この新しいイニシャライザは、提供された center の点と size の値に基づいて、適切な原点を計算することで始まります。イニシャライザは、その後適切なプロパティに新しい原点とサイズの値を格納する、構造体の自動化したメンバ化イニシャライザ init(orgin:size:) を呼び出します。
拡張機能は、既存の型に新しいインスタンスメソッドと型メソッドを追加できます。以下の例では、Int 型に repetitions と言う新しいインスタンスメソッドを追加しています。
repetitions(task:) メソッドは、( ) -> Void 型の一つの引数を取り、パラメータのない、戻り値のない関数である事を示しています。
この拡張機能を定義した後、何回でも多くの回数タスクを実行するために任意の整数で repetitions(task:) メソッドを呼び出すことができます。
拡張機能で追加されたインスタンス・メソッドは、インスタンス自体を変更 (または 変異) することもできます。self を変更する構造体と列挙型のメソッド、またはそのプロパティはちょうどオリジナルの実装からメソッドを変異するように、mutating でインスタンス・メソッドをマークしなければなりません。
以下の例では、Swift の Int 型に、square (自乗) と言う新しい変異メソッドを追加し、それはオリジナルの値を自乗します:
拡張機能は、既存の型に新しいサブスクリプトを追加できます。以下の例では、Swift の組み込み Int 型に整数のサブスクリプト (添字) を追加します。このサブスクリプト [n] は、数字の右側から、十進数で n 番目の数字を返します。
...などなど:
Int 値が要求されたインデックスに対して十分な桁数を持っていない場合は、数字が左に 0 で埋められたかのように、サブスクリプトの実装は、0 を返します。
拡張機能は、既存のクラス、構造体及び列挙型に新しいネストした型を追加できます。
この例では、Int に新たなネストした列挙型を追加しています。Kind と言うこの列挙型は、特定の整数が表す数字の種類を表現します。具体的には、数字は、負か、ゼロか、または正かを表します。
またこの例では、その整数に対する適切な Kind の列挙型 case を返すように、kind と言う、Int に新しい計算されたインスタンスプロパティを追加します。
ネストした列挙型は、任意の Int 値で使用できるようになります。
この関数、printIntegerKinds(_:) は、Int 値の入力配列を取り、順番にそれらの値を反復処理します。配列内の各整数の場合、関数はその整数の kind の計算されたプロパティを考慮し、適切な説明を出力します。