Swift 5.8 日本語化計画 : Swift 5.8


拡張機能


既存の型に機能を追加します。


拡張機能 は、既存のクラス、構造体、列挙型、またはプロトコル型に新しい機能を追加します。これは、(逆行的モデリング として知られている) 元のソースコードへのアクセス権を持っていない型を拡張する機能を含んでいます。拡張機能は、Objective-C のカテゴリに似ています。(Objective-C のカテゴリとは異なり、Swift の拡張機能には名前がありません。)


Swift の拡張機能は以下のことができます:


Swift では、その要件の実装を提供し、準拠する型を活用できる機能を追加するためのプロトコルを拡張することもできます。詳細については、プロトコル拡張機能 を参照してください。


注意: 拡張機能は、型に新しい機能を追加できますが、既存の機能をオーバーライドすることはできません。


拡張機能の構文


extension キーワードを使用して拡張機能を宣言します。


  1. extension SomeType {
  2. // new functionality to add to SomeType goes here
  3. }


拡張機能は、1つ以上のプロトコルを採用するために、既存の型を拡張できます。プロトコルの準拠を追加するには、クラスまたは構造体を書くのと同じ方法でプロトコル名を記述して下さい。


  1. extension SomeType: SomeProtocol, AnotherProtocol {
  2. // implementation of protocol requirements goes here
  3. }


このようなプロトコル準拠の追加は 拡張機能を持つプロトコル準拠の追加 で説明されています。



汎用型の拡張 で説明したように、拡張機能を使用して、既存の汎用型を拡張することができます。汎用の Where 句を含む拡張機能 で説明したように、汎用型を拡張して条件付きで機能を追加することもできます。


注意: 既存の型に新しい機能を追加するために拡張機能を定義すると、拡張機能が定義される前にそれらが作成された場合でも、その型のすべての既存のインスタンス上で新しい機能が利用できるようになります。


計算されたプロパティ


拡張機能は、既存の型に、計算されたインスタンスプロパティと計算された型プロパティを追加できます。この例では、距離の単位を扱うための基本的なサポートを提供するために、Swift の組み込みの Double 型に5つの計算されたインスタンスプロパティを追加します。


  1. extension Double {
  2. var km: Double { return self * 1_000.0 }
  3. var m: Double { return self }
  4. var cm: Double { return self / 100.0 }
  5. var mm: Double { return self / 1_000.0 }
  6. var ft: Double { return self / 3.28084 }
  7. }
  8. let oneInch = 25.4.mm
  9. print("One inch is \(oneInch) meters")
  10. // prints "One inch is 0.0254 meters"
  11. let threeFeet = 3.ft
  12. print("Three feet is \(threeFeet) meters")
  13. // prints "Three feet is 0.914399970739201 meters"


これらの計算されたプロパティは、長さの特定の単位として Double 値が考えられるべきだと表します。それらは計算されたプロパティとして実装されていますが、これらのプロパティの名前は、距離の変換を実行するために、そのリテラル値を使用する方法として、ドット構文を持つ浮動小数点リテラル値に追加できます。


この例では、1.0Double 値は "1メートル" を表すと考えられます。これは、m の計算されたプロパティが self を返し、式 1.m1.0Double 値を計算するとみなされるためです。


他の単位はメートルで測定した値として表現するためにいくつかの変換が必要です。1 キロメートルは、1000 メートルと同じで、km の計算されたプロパティはメートルで表した数値に変換するため 1_000.00 の値を乗算します。同様に、1メートルは 3.28084 フィートであり、フィートをメートルに変換するには ft の計算されたプロパティは 3.28084 で基本的な Double 値を除算します。


これらのプロパティは、読み取り専用の計算されたプロパティで、したがってそれらは簡潔にするために、get キーワードなしで表わされています。それらの戻り値は Double 型であり、Double が受け入れられる場所ならどこでも数学的計算の中で使用できます:


  1. let aMarathon = 42.km + 195.m
  2. print("A marathon is \(aMarathon) meters long")
  3. // prints "A marathon is 42195.0 meters long"


注意: 拡張機能は、新しい計算されたプロパティを追加できますが、格納されたプロパティを追加したり、既存のプロパティにプロパティ監視者を追加したりはできません。


イニシャライザ


拡張機能は、既存の型に新しいイニシャライザを追加できます。これは、イニシャライザ・パラメータとして独自のカスタム型を受け入れるように他の型を拡張する事を可能にし、または型のオリジナルの実装の一部としては含まれていなかった追加の初期化オプションを提供できます。


拡張機能は、クラスに新しいコンビニエンス・イニシャライザを追加できますが、クラスに新しい指定イニシャライザまたはデイニシャライザの追加はできません。指定イニシャライザとデイニシャライザは、常にオリジナルのクラスの実装によって提供されなければなりません。



拡張機能を使用して、その格納されたプロパティすべてにデフォルト値を提供する値型にイニシャライザを追加できますが、カスタムイニシャライザを定義しないし、その拡張機能のイニシャライザ内からその値型のデフォルトのイニシャライザおよびメンバ化イニシャライザを呼び出すことができます。値型のイニシャライザデリゲート で説明したように、イニシャライザを値型のオリジナルの実装の一部として記述した場合は、これはあてはまりません。


拡張機能を使用して別のモジュール内で宣言された構造体にイニシャライザを追加した場合、新しいイニシャライザは定義しているモジュールからイニシャライザを呼び出すまで self にアクセスできません。


以下の例では、幾何学的な長方形を表すためにカスタムの Rect 構造体を定義しています。また、この例では、SizePoint と言う、2つのサポートする構造体も定義しており、どちらも全てのプロパティに 0.0 のデフォルト値を提供しています。


  1. struct Size {
  2. var width = 0.0, height = 0.0
  3. }
  4. struct Point {
  5. var x = 0.0, y = 0.0
  6. }
  7. struct Rect {
  8. var origin = Point()
  9. var size = Size()
  10. }


Rect 構造体は、そのすべてのプロパティのデフォルト値を提供するので、それは デフォルトのイニシャライザ で説明したように、自動的にデフォルトのイニシャライザとメンバ化イニシャライザを受け取ります。これらのイニシャライザは、新しい Rect インスタンスを作成するために使用できます:


  1. let defaultRect = Rect()
  2. let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0),
  3. size: Size(width: 5.0, height: 5.0))


特定の中心点とサイズを取る追加のイニシャライザを提供するために、Rect 構造体を拡張できます。


  1. extension Rect {
  2. init(center: Point, size: Size) {
  3. let originX = center.x - (size.width / 2)
  4. let originY = center.y - (size.height / 2)
  5. self.init(origin: Point(x: originX, y: originY), size: size)
  6. }
  7. }


この新しいイニシャライザは、提供された center の点と size の値に基づいて、適切な原点を計算することで始まります。イニシャライザは、その後適切なプロパティに新しい原点とサイズの値を格納する、構造体の自動化したメンバ化イニシャライザ init(orgin:size:) を呼び出します。


  1. let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
  2. size: Size(width: 3.0, height: 3.0))
  3. // centerRect's origin is (2.5, 2.5) and its size is (3.0, 3.0)


注意: 拡張機能を持つ新しいイニシャライザを提供する場合でも、あなたにはイニシャライザが完了するやいなや、各インスタンスは完全に初期化されていることを確認する責任があります。


メソッド


拡張機能は、既存の型に新しいインスタンスメソッドと型メソッドを追加できます。以下の例では、Int 型に repetitions と言う新しいインスタンスメソッドを追加しています。


  1. extension Int {
  2. func repetitions(task: () -> Void) {
  3. for _ in 0..<self {
  4. task()
  5. }
  6. }
  7. }


repetitions(task:) メソッドは、() -> Void 型の一つの引数を取り、パラメータのない、戻り値のない関数である事を示しています。


この拡張機能を定義した後、何回でも多くの回数タスクを実行するために任意の整数で repetitions(task:) メソッドを呼び出すことができます。


  1. 3.repetitions{
  2. print("Hello!")
  3. }
  4. // Hello!
  5. // Hello!
  6. // Hello!


変異インスタンスメソッド


拡張機能で追加されたインスタンス・メソッドは、インスタンス自体を変更 (または 変異) することもできます。self を変更する構造体と列挙型のメソッド、またはそのプロパティはちょうどオリジナルの実装からメソッドを変異するように、mutating でインスタンス・メソッドをマークしなければなりません。


以下の例では、Swift の Int 型に、square (自乗) と言う新しい変異メソッドを追加し、それはオリジナルの値を自乗します:


  1. extension Int {
  2. mutating func square() {
  3. self = self * self
  4. }
  5. }
  6. var someInt = 3
  7. someInt.square()
  8. // someInt is now 9


サブスクリプト


拡張機能は、既存の型に新しいサブスクリプトを追加できます。以下の例では、Swift の組み込み Int 型に整数のサブスクリプト (添字) を追加します。このサブスクリプト [n] は、数字の右側から、十進数で n 番目の数字を返します。



...などなど:


  1. extension Int {
  2. subscript(digitIndex: Int) -> Int {
  3. var decimalBase = 1
  4. for _ in 0..<digitIndex {
  5. decimalBase *= 10
  6. }
  7. return (self / decimalBase) % 10
  8. }
  9. }
  10. 746381295[0]
  11. // returns 5
  12. 746381295[1]
  13. // returns 9
  14. 746381295[2]
  15. // returns 2
  16. 746381295[8]
  17. // returns 7


Int 値が要求されたインデックスに対して十分な桁数を持っていない場合は、数字が左に 0 で埋められたかのように、サブスクリプトの実装は、0 を返します。


  1. 746381295[9]
  2. // returns 0, as if you had requested:
  3. 0746381295[9]


ネストした型


拡張機能は、既存のクラス、構造体及び列挙型に新しいネストした型を追加できます。


  1. extension Int {
  2. enum Kind {
  3. case negative, zero, positive
  4. }
  5. var kind: Kind {
  6. switch self {
  7. case 0:
  8. return .zero
  9. case let x where x > 0:
  10. return .positive
  11. default:
  12. return .negative
  13. }
  14. }
  15. }


この例では、Int に新たなネストした列挙型を追加しています。Kind と言うこの列挙型は、特定の整数が表す数字の種類を表現します。具体的には、数字は、負か、ゼロか、または正かを表します。


またこの例では、その整数に対する適切な Kind の列挙型 case を返すように、kind と言う、Int に新しい計算されたインスタンスプロパティを追加します。


ネストした列挙型は、任意の Int 値で使用できるようになります。


  1. func printIntegerKinds(_ numbers: [Int]) {
  2. for number in numbers {
  3. switch number.kind {
  4. case .negative:
  5. print("- ", terminator: "")
  6. case .zero:
  7. print("0 ", terminator: "")
  8. case .positive:
  9. print("+ ", terminator: "")
  10. }
  11. }
  12. print("")
  13. }
  14. printIntegerKinds([3, 19, -27, 0, -6, 0, 7])
  15. // prints "+ + - 0 - 0 +"


この関数、printIntegerKinds(_:) は、Int 値の入力配列を取り、順番にそれらの値を反復処理します。配列内の各整数の場合、関数はその整数の kind の計算されたプロパティを考慮し、適切な説明を出力します。


注意: number.kind は既に Int.Kind 型であることがわかっています。このため、Int.Kind case 値のすべては、Int.Kind.negative ではなく、.negative のように、switch 文の中では省略形で書くことができます。


前:ネストした型 次:プロトコル
















トップへ












トップへ












トップへ












トップへ
目次
Xcode の新機能

Swift について
Swift と Cocoa と Objective-C (obsolete)
Swift Blog より (obsolete)

SwiftLogo
  • Swift 5.8 全メニュー


  • Swift へようこそ
  • Swift について
  • Swift 言語のガイド
  • Swift の基本
  • 基本演算子
  • 文字列と文字
  • コレクション型
  • フロー制御
  • 関数
  • クロージャ
  • 列挙型
  • 構造体とクラス
  • プロパティ
  • メソッド
  • サブスクリプト
  • 継承
  • 初期化
  • デイニシャライザ
  • Optional の連鎖
  • エラー処理
  • 同時実行
  • 型キャスト
  • ネストした型
  • 拡張機能
  • プロトコル
  • ジェネリック(汎用)
  • 自動参照カウント
  • メモリの安全性
  • アクセス制御
  • 高度な演算子

  • 言語リファレンス

  • マニュアルの変更履歴













  • トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ







    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ









    トップへ