高度な演算子


基本演算子 で説明した演算子に加えて、Swift は、より複雑な値操作を実行する、いくつかの高度な演算子を提供しています。これらは C や Objective-C で精通しているであろう、ビット単位とビットシフト演算子のすべてを含んでいます。


C での算術演算子とは異なり、Swift における算術演算子は、デフォルトではオーバーフローしません。オーバーフロー動作はトラップされ、エラーとして報告されます。オーバーフローする動作を選択するには、Swift の算術演算子の第2セットを使用し、それらはデフォルトでオーバーフローする、加算演算子(&+)などを使用して下さい。これらのオーバーフロー演算子はすべてアンパサンド(&)で始まります。


独自の構造体、クラス、および列挙型を定義する際には、これらのカスタム型の標準 Swift 演算子の独自の実装を提供するのが役立ちます。Swift は、簡単にこれらの演算子のおあつらえの実装を提供し、それらの動作は、作成する各々の型ごとにどうするべきかを正確に決定できます。


これは事前に定義された演算子に限定されることではありません。Swift はカスタムの優先順位と結合値で、独自のカスタムの挿入辞、接頭辞、接尾辞、および代入演算子を定義する自由を与えます。これらの演算子を使用し、事前に定義された演算子のように、コード内で使用し採用し、そして定義したカスタム演算子をサポートするために、既存の型を拡張することさえもできます。



ビット単位演算子


ビット単位演算子 で、データ構造体の中の個々の生データのビットを操作できます。それらはしばしば、グラフィック・プログラミングおよびデバイスドライバの作成のように、低レベルのプログラミングに使用されます。カスタムプロトコルによる通信用のデータの符号化と復号化などのような外部ソースからの生データで作業する場合にもビット単位演算子は役立ちます。


下記のように Swift は、C 言語で見られるビット単位の演算子のすべてをサポートしています。



ビット単位の NOT 演算子


ビット単位の NOT 演算子 (~)は、数のすべてのビットを反転します:


bitwiseNOT_2x


ビット単位の NOT 演算子は、接頭辞演算子であり、それが操作する値の直前に、全く空白をおかずに書きます。


  1. let initialBits: UInt8 = 0b00001111
  2. let invertedBits = ~initialBits        // equals 11110000


UInt8 整数は 8 ビットであり、0255 の間の全ての値を格納できます。この例では、その最初の4ビットが 0 に設定されており、次の4ビットが 1 に設定された2進数値の 00001111UInt8 整数を初期化しています。これは 十進数の 15 に等しいです。


ビット単位の NOT 演算子は、その後、全てのビットが反転した initialBits に等しい invertedBits と言う新しい定数を作成するために使用されます。ゼロは1になり、1はゼロになります。 invertedBits の値は 11110000 となり、符号なし十進数の 240 に等しくなります。



ビット単位の AND 演算子


ビット単位の AND 演算子 (&) は、2つの数のビットを組み合わせます。それは、そのビットの 両方の 入力の数が 1 に等しい場合にのみ、そのビットが 1 に設定されている新しい数字を返します。


bitwiseAND_2x


以下の例では、firstSixBitslastSixBits の値の両方が 1 に等しい4つの中央のビットを持っています。ビット単位の AND 演算子は、それらを組み合わせて符号なし十進数の 60 に等しい数 00111100 を作ります。


  1. let firstSixBits: UInt8 = 0b11111100
  2. let lastSixBits : UInt8 = 0b00111111
  3. let middleFourBits = firstSixBits & lastSixBits    // equals 00111100


ビット単位の OR 演算子


ビット単位の OR 演算子 (|) は2つの数のビットを比較します。演算子は、入力した数の いずれか1 に等しい場合、そのビットを 1 に設定して、新しい数字を返します。


bitwiseOR_2x


以下の例では、someBitsmoreBits の値が異なるビットは 1 に設定されます。ビット単位の OR 演算子はそれらを組み合わせて 254 の符号なし十進数に等しい数 11111110 を作ります。


  1. let someBits: UInt8 = 0b10110010
  2. let moreBits: UInt8 = 0b01011110
  3. let combinedbits = someBits | moreBits    // equals 11111110


ビット単位の XOR 演算子


ビット単位の XOR 演算子、または "排他的論理和演算子" (^) は、2つの数のビットを比較します。演算子は、その入力ビットが異なっていれば 1 に設定され、入力ビットが同じであれば 0 に設定して新しい数字を返します。


bitwiseXOR_2x


以下の例では、firstBitsotherBits の値はそれぞれ、相手にはない場所にはビットを 1 に設定されます6。ビット単位の XOR 演算子は、その出力値でこれらのビットの両方を 1 に設定します。firstBitsotherBits が一致する他のすべてのビットは出力値で 0 に設定されます。


  1. let firstBits: UInt8 = 0b00010100
  2. let otherBits: UInt8 = 0b00000101
  3. let outputBits = firstBits ^ otherBits    // equals 00010001



ビット単位の左と右シフト演算子


ビット単位の左シフト演算子 (<<) と ビット単位の右シフト演算 (>>) は、以下に定義された規則に従って、左か右に特定の数だけ数字のすべてのビットを移動します。


ビット単位の左と右シフトは、2の要素で整数を乗算または除算する効果があります。整数のビットを一つの位置左にシフトすることは、その値を2倍にし、一方、一つの位置右にシフトすると、その値を半分にします。


符号なし整数のシフト動作


符号なし整数のビットシフト動作は以下のとおりです。


  1. 既存のビットは、左または右に要求された場所の数だけ移動されます。
  2. 整数の保管場所の境界を越えて移動されたすべてのビットは破棄されます。
  3. 元のビットの、左または右に移動された後のスペースにはゼロが挿入されます。


このアプローチは、論理シフト として知られています。


下の図は、(111111111 箇所だけ左にシフトする) 11111111 << 1 と、(111111111 箇所だけ右にシフトする) 11111111 >> 1 の結果を示しています。青い数字はシフトされ、灰色の数字は破棄され、オレンジ色のゼロが挿入されています。


bitshiftUnsigned_2x


ここでビットのシフトが Swift のコード内でどのように見えるかを示します:


  1. let shiftBits: UInt8 = 4        //00000100 in binary
  2. shiftBits<<1                        //00001000
  3. shiftBits<<2                        //00010000
  4. shiftBits<<5                        //10000000
  5. shiftBits<<6                        //00000000
  6. shiftBits>>2                        //00000001


他のデータ型の値をコード化し、解読するために、ビットシフトを使用できます。


  1. let pink: UInt32 = 0xCC6699
  2. let redComponent = (pink & 0xFF0000) >> 16        // redComponent is 0xCC, or 204
  3. let greenComponent = (pink & 0x00FF00) >> 8      // greenComponent is 0x66, or 102
  4. let blueComponent = pink & 0x0000FF                    // blueComponent is 0x99, or 153


この例では、ピンク色用のカスケーディングスタイルシートの色値を格納するために pink と言う UInt32 型の定数を使用しています。CSS カラー値 #CC6699 は、Swift の16進数表現で 0xCC6699 として書かれています。この色は、ビット単位の AND 演算子 (&) とビット単位の右シフト演算子 (>>)によって、その赤 (CC)、緑 (66)、青 (99) の成分に分解されます。


赤色の成分は、数値 0xCC66990xFF0000 間でビット単位の AND を実行することによって得られます。0xFF0000 内のゼロは効果的に 0xCC6699 の2番目と3番目のバイトを "マスク" し、6699 は無視され、結果として 0xCC0000 を残します。


この数字は、その後右へ16箇所シフトされます (>> 16)。16進数で文字の各ペアは 8 ビットなので、右に16箇所移動すると 0xCC00000x0000CC にに変換されます。これは 10 進値の 204 である 0xcc と同じです。


同様に、緑色の成分は数値 0xCC66990x00FF00 間でビット単位の AND を行うことにより得られ、0x006600 の出力値を得られます。この出力値は、さらに右に8箇所シフトし、10 進値の 102 である 0x66 の値を得ます。


最後に、青色の成分は、数値 0xCC66990x0000FF 間でビット単位の AND を行うことにより、0x000099 の出力値を得られます。0x000099 はすでに 10 進値の 153 である 0x99 に等しいので、これを右にシフトする必要はありません。


符号付き整数のシフト動作


シフト動作は、符号付き整数が二進法で表現されているため、符号なし整数の場合よりも符号付き整数の方が、より複雑です。(簡単にするために、8 ビット符号付き整数に基づいて下に例を挙げますが、同じ原理は、どんな大きさの符号付き整数にも当てはまります)


符号付き整数は、整数が正か負かを示すために (符号ビット として知られる) その最初のビットを使用します。0 の符号ビットは正を意味し、1 の符号ビットは負を意味します。


(値ビット として知られる) 残りのビットは、実際の値を格納します。正の数は、0 から数え上げて符号なし整数の場合とまったく同じ方法で格納されます。ここでは Int8 内部のビットが数 4 の場合どう見えるか示します。


bitshiftSignedFour_2x


符号ビットは 0 ("正" を意味します) で、7つの値ビットが2進数表記で書かれた 4 の数です。


負の数は、しかし、異なる方法で格納されます。それらは、n が値ビット数である 2n 乗の絶対値から減算して格納されます。8ビットの数には7つの値ビットがあるので、これは、27 乗、または 128 を意味します。


ここで Int8 内部のビットが数 -4 の時どう見えるか示します。


bitshiftSignedMinusFour_2x


このとき、符号ビットは 1 ("負" の意味) で、7つの値ビットには、124 (128 - 4 です) の二進値があります。


bitshiftSignedMinusFourValue_2x


この負の数の符号化は、2の補数 表現として知られています。これは、負の数を表すために、普通でない方法に見えるかもしれませんが、いくつかの利点があります。


まず、単に (符号ビットを含む) 全8ビットの標準バイナリ加算を行うと、-1-4 に加算することができ、終わったら8ビットに収まらないものは破棄します:


bitshiftSignedAddition_2x


次に、2の補数表現はまた、正の数のように負の数のビットを左右にシフトし、左シフトして2倍の数を得、またはそれらを右シフトして半分の数を得ます。これを達成するためには、符号付き整数を右にシフトするときの、追加のルールが使用されます。右に符号付き整数をシフトする場合、符号なし整数の場合と同じルールを適用し、ゼロではなく、符号ビット を使用して左側の空のビットを埋めます。


bitshiftSigned_2x


このアクションは、それらが右にシフトされた後、符号付き整数が、同じ符号であることを保証するので、算術シフト として知られています。


正と負の数が格納されている特別な方法のため、それらのいずれを右にシフトしてもゼロに近づきます。このシフトの間、符号ビットを同じに維持することは、それらの値がゼロに近づく間負の整数が負のままであることを意味します。



オーバーフロー演算子


整数の定数や変数に数字を挿入しようとして値を保持できない場合、デフォルトでは Swift は、無効な値が作成されるのを許可するのではなく、エラーを報告します。この動作は、大きすぎるか小さすぎる数字で作業するのに特別の安全性を提供します。


たとえば、Int16 の整数型は -32768 から 32767 の間の全ての符号付き整数を保持できます。この範囲外の数に Int16 の定数または変数を設定しようとすると、エラーが発生します。


  1. var potentialOverflow = Int16.max
  2. // potentialOverflow equals 32767, which is the largest value an Int16 can hold
  3. potentialOverflow += 1
  4. // this causes an error


境界値条件をコード化するとき値が大きすぎるか小さすぎる時のエラー処理を提供することは、より多くの柔軟性を与えます。


しかし、利用可能なビット数を切り捨てるオーバーフロー状態を特に望む場合、エラーを引き起こすよりも、この動作を選択できます。Swift は、3つの算術 オーバーフロー演算子 を提供し、整数計算のオーバーフロー動作を選択できます。これらの演算子はすべて、アンパサンド (&) で始まります。




訳注: Swift 1.0 ではこの他 オーバーフロー除算 (&/)及びオーバーフロー剰余(&%)が有効でしたが、削除されました。


値オーバーフロー


数値は、正と負両方の方向にオーバーフローする可能性があります。


ここで符号なしの整数値をオーバーフロー加算演算子 (&+) を使用して正の方向にオーバーフローさせるのが許されると、何が起こるか例を示します。


  1. var unsignedOverflow = UInt8.max
  2. // unsignedOverflow equals 255, which is the maximum value a UInt8 can hold
  3. unsignedOverflow = unsignedOverflow &+ 1
  4. // willOverflow is now equal to 0


変数 unsignedOverflowUInt8 が保持できる最大値 (255、または2進数で 11111111) で初期化されます。次いで、それはオーバーフロー加算演算子 (&+) を用いて、1 だけ増分されます。これは UInt8 が保持できる大きさをちょうど超えるその 2 進数表現をプッシュし、その境界を越えてオーバーフローを引き起こし、以下の図のようになります。オーバーフロー加算後 UInt8 の範囲内にとどまる値は 00000000、またはゼロです。


overflowAddition_2x


似たような事が、符号なし整数を負の方向にオーバーフローさせると発生します。ここに、オーバーフロー減算演算子(&-)を使用した例を示します:


  1. var unsignedOverflow = UInt8.min
  2. // unsignedOverflow equals 0, which is the minimum value a UInt8 can hold
  3. unsignedOverflow = unsignedOverflow &- 1
  4. // unsignedOverflow is now equal to 255


UInt8 が保持できる最小値はゼロ、または2進数で 00000000 です。オーバーフロー減算演算子(&-)を使用して 00000000 から 1 を減算した場合、数がオーバーフローし、11111111、または 十進数で 255 になります。



overflowUnsignedSubtraction_2x


同じようなオーバーフローは、符号付き整数でも発生します。符号付き整数のすべての加算と減算は、ビット単位の左と右シフト演算子 で説明したように、符号ビットが加算または減算される数字の部分として含まれ、ビット単位の方法で行われます。



  1. var signedOverflow = Int8.min
  2. // signedOverflow equals -128, which is the smallest value an Int8 can hold
  3. signedOverflow = signedUnderflow &- 1
  4. // signedOverflow is now equal to 127


Int8 が保持できる最小値は -128、または2進数で 10000000 です。オーバーフロー演算子でこの2進数から 1 を減算すると、符号ビットを入れ替え、正の 127 となり、Int8 が保持できる最大の正の値 01111111 の2進数値を与えます。



overflowSignedSubtraction_2x


符号付きと符号なし両方の整数の場合、最大の有効な整数値から正の方向へのオーバフローは最小の方向になり、最小値から負の方向のへオーバーフローは最大値になります。


優先順位と結合性


演算子の 優先順位 は、一部の演算子に他よりも高い優先度を与えます。これらの演算子が最初に適用されます。


演算子の 結合性 は、同じ優先順位の演算子が一緒にグループ化され、左からグループ化されるか、または右からグループ化されます。"それらはその左の式に結合される"、または "それらはその右の式に結合される"、の意味であると考えて下さい。


これは、複合式が計算される順序を操作するとき、各演算子の優先順位と結合性を考慮することは重要です。例えば、なぜ以下の式は 17 に等しいか、演算子の優先順位が説明します。


  1. 2 + 3 % 4 * 5
  2. // this equals 17


左から右に厳密に考えると、以下のようにこの式を計算できます。


しかし、実際の答えは 5 ではなく 17 です。より高い優先順位の演算子は、優先順位の低いものより前に評価されます。Swift では、C のように、乗算演算子 (*) 及び剰余演算子 (%) は、加算演算子 (+) よりも高い優先順位です。結果として、加算が考慮される前に、それらは両方とも評価されます。


しかし、乗算と剰余は互いに 同じ 優先順位です。使用するために正確な評価順序で操作するには、それらの結合性も考慮する必要があります。乗算と剰余はその左の式と、両方とも結合されます。それらの左から順に、式のこれらの部分の周りに暗黙の括弧を追加するとこう考えられます。


2 + ((3 % 4) * 5)


(3 % 4)3 なので、これは以下と等価です:


2 + (3 * 5)



(3 * 5 )15 なので、これは以下と等価です:


2 + 15



この計算の最終的な答えは 17 が得られます。


演算子優先順位グループと結合性の完全なリストを含む、Swift 標準ライブラリが提供する演算子についての詳細は、演算子宣言 を参照してください。


注意: Swift の演算子の優先順位と結合性のルールは簡単で、C や Objective-C に見られるものよりも予測可能です。しかし、これはそれらが C ベースの言語と全く同じではないことを意味します。その演算子の相互作用はまだ Swift に既存のコードを移植するときに、意図したとおりに動作を保証するように注意してください。


演算子メソッド


クラスと構造体は、既存の演算子の独自の実装を提供できます。これは、既存の演算子を オーバーロードする 事として知られています。


以下の例は、カスタム構造体のための算術加算演算子 (+) を実装する方法を示しています。算術加算演算子は二つのターゲット上で演算するので 二項演算子 であり、それら二つのターゲットの間に表示されるので、挿入辞(infix) であると言われます。


以下の例では、二次元の位置ベクトル (x,y) のための Vector2D 構造体の定義に続いて、Vector2D 構造体のインスタンスを一緒に加算する 演算子メソッド の定義が続きます。


  1. struct Vector2D {
  2.         var x = 0.0, y = 0.0
  3. }
  4. extension Vector2D {
  5.         static func + (left: Vector2D, right: Vector2D) -> Vector2D {
  6.                 return Vector2D(x: left.x + right.x, y: left.y + right.y)
  7.         }
  8. }


演算子メソッドは、オーバーロードする演算子 (+) と一致するメソッド名を持つ Vector2D 上の型メソッドとして定義されています。加算は、ベクトルのために不可欠な動作の一部ではないので、型メソッドは、Vector2D の主構造体の宣言よりもむしろ Vector2D の拡張機能内で定義されています。算術加算演算子は二項演算子であるため、この演算子メソッドは、型 Vector2D の2つの入力パラメータを取り、また型 Vector2D である、単一の出力値を返します。


この実装では、入力パラメータは leftright と名付けられ、+ 演算子の左側と右側になる Vector2D インスタンスを表現します。メソッドは、xy プロパティが、一緒に加算された2つの Vector2D インスタンスからの xy プロパティの和で初期化された、新しい Vector2D インスタンスを返します。


型メソッドは、既存の Vector2D インスタンス間の挿入辞(infix) 演算子として使用できます。


  1. let vector = Vector2D(x: 3.0, y: 1.0)
  2. let anotherVector = Vector2D(x: 2.0, y: 4.0)
  3. let combinedVector = vector + anotherVector
  4. // combinedVector is a Vector2D instance with values of (5.0, 5.0)


この例は、以下の図に示すように、ベクトル (3.0, 1.0)(2.0, 4.0) を一緒に加算するとベクトル (5.0,5.0) になる事を示しています。



vectorAddition_2x


接頭辞と接尾辞演算子


上記の例では、二項の挿入辞演算子のカスタムの実装を示しました。クラスと構造体も標準 単項演算子 の実装も提供できます。単項演算子は、一つのターゲットに作用します。それらは (-a のように) それらのターゲットの前ならば、接頭辞 であり、それらが (b! のように) それらのターゲットの後に続く場合、それらは 接尾辞 演算子です。


演算子メソッドを宣言するとき、func キーワードの前に prefix または postfix 修飾子を書くことで単項演算子の接頭辞や接尾辞を実装できます:


  1. extension Vector2D {
  2.         static prefix func - (vector: Vector2D) -> Vector2D {
  3.                 return Vector2D(x: -vector.x, y: -vector.y)
  4.         }
  5. }


上記の例は、Vector2D インスタンスの単項マイナス演算子 (-a) を実装しています。単項マイナス演算子は接頭辞演算子なので、このメソッドは prefix 修飾子で修飾する必要があります。


簡単な数値の場合、単項マイナス演算子は、正の値を同等の負の値に変え、またその逆に変換します。 Vector2D インスタンスの対応する実装は、xy プロパティの両方でこの操作を実行します。


  1. let positive = Vector2D(x: 3.0, y: 4.0)
  2. let negative = -positive
  3. // negative is a Vector2D instance with values of (-3.0, -4.0)
  4. let alsoPositive = -negative
  5. // alsoPositive is a Vector2D instance with values of (3.0, 4.0)


複合代入演算子


複合代入演算子 は、別の操作を代入(=) と組み合わせます。例えば、加算代入演算子 (+=) は、加算と代入を1つの操作に組み合わせています。パラメータの値は、演算子メソッドの中から直接変更されますので、inout として複合代入演算子の左入力パラメータ型をマークして下さい。


以下の例は、Vector2D インスタンスの加算代入演算子メソッドを実装しています。


  1. extension Vector2D {
  2.         static func += (left: inout Vector2D, right: Vector2D) {
  3.                 left = left + right
  4.         }
  5. }


加算演算子が先に定義されているので、ここで加算処理を再実装する必要はありません。代わりに、加算代入演算子メソッドは、既存の加算演算子メソッドを利用し、左の値を左の値プラス右の値となるように、設定するために使用します。


  1. var original = Vector2D(x: 1.0, y: 2.0)
  2. let vectorToAdd = Vector2D(x: 3.0, y: 4.0)
  3. original += vectorToAdd
  4. // original now has values of (4.0, 6.0)


注意: デフォルトの代入演算子 (=) をオーバーロードすることはできません。複合代入演算子のみがオーバーロードできます。同様に、三項条件演算子 (a ? b:c) もオーバーロードすることはできません。


等価演算子


カスタムのクラスと構造体は、"等価" 演算子 (==) と "不等価" 演算子 (!=) として知られる 等価演算子 のデフォルトの実装を受信しません。Swift は "等しい" の意味が、コード内でこれらの型が果たしている役割に依存しているため、独自のカスタム型の "等しい" として適するかを推測することはできません。


独自のカスタム型の同等性をチェックする、等価演算子を使用するには、他の挿入辞演算子の場合と同様に演算子の実装を提供して下さい:


  1. extension Vector2D {
  2. static func == (left: Vector2D, right: Vector2D) -> Bool {
  3.         return (left.x == right.x) && (left.y == right.y)
  4. }
  5.         static func != (left: Vector2D, right: Vector2D) -> Bool {
  6.                 return !(left == right)
  7.         }
  8. }


上記の例では、2つの Vector2D インスタンスが同等の値を持っているかを、"等価" 演算子 (==) でチェックするために実装しています。Vector2D の文脈では、"両方のインスタンスが同じ x 値と y 値を持つ" という意味で、"等しい" と考慮することに意味があり、これは、演算子の実装によって使用される論理です。また、この例では、"等価" 演算子の結果の逆を単に返す (!=)、"不等価"演算子も実装しています。


これで、2つの Vector2D インスタンスが等価であるかどうかをチェックするために、これらの演算子を使えるようになりました。


  1. let twoThree = Vector2D(x: 2.0, y: 3.0)
  2. let anotherTwoThree = Vector2D(x: 2.0, y: 3.0)
  3. if twoThree == anotherTwoThree {
  4.         print("These two vectors are equivalent.")
  5. }
  6. // prints "These two vectors are equivalent."


カスタム演算子


Swift で提供される標準の演算子に加えて、独自の カスタム演算子 を宣言し、実装できます。カスタム演算子を定義するために使用できる文字の一覧については、演算子 を参照してください。


新しい演算子は、operator のキーワードを使用して、グローバルレベルで宣言され、prefix、infix または postfix 修飾子でマークされます:


prefix operator +++



上記の例では、+++ と言う新しい接頭辞演算子を定義しています。この演算子は、Swift では既存の意味がないので、それは Vector2D インスタンスとの作業の具体的な文脈で、独自のカスタムの意味を以下で与えられています。この例の目的は、+++ が新しい "接頭辞倍増" 演算子として扱われる事です。それは Vector2D インスタンスの xy 値を倍にし、以前に定義された、加算代入演算子でそれ自体にベクトルを加算します:


  1. extension Vector2D
  2.         static prefix func +++ (vector: inout Vector2D) -> Vector2D {
  3.                vector += vector
  4.                return vector
  5.         }
  6. }
  7. var toBeDoubled = Vector2D(x: 1.0, y: 4.0)
  8. let afterDoubling = +++toBeDoubled
  9. // toBeDoubled now has values of (2.0, 8.0)
  10. // afterDoubling also has values of (2.0, 8.0)


カスタム挿入辞演算子の優先順位


カスタム infix (挿入辞) 演算子もそれぞれ優先順位グループに属しています。優先順位グループは、他の挿入辞演算子に対する演算子の優先順位だけでなく、演算子の結合性も指定します。これらの特性が、他の挿入辞演算子と挿入辞演算子の相互作用にどのように影響するかの詳細については、優先順位と結合性 を参照してください。


明示的に優先順位のグループに配置されていないカスタムの挿入辞演算子は、三項条件演算子の優先順位よりも高い優先順位で、デフォルトの優先順位のグループを与えられています。


以下の例では、+- と言う新しいカスタムの挿入辞演算子を定義し、それは優先グループ AdditionPrecedence に属しています:


  1. infix operator +-: AdditionPrecedence
  2. extension Vector2D {
  3.         static func +- (left: Vector2D, right: Vector2D) -> Vector2D {
  4.                 return Vector2D(x: left.x + right.x, y: left.y - right.y)
  5.         }
  6. }
  7. let firstVector = Vector2D(x: 1.0, y: 2.0)
  8. let secondVector = Vector2D(x: 3.0, y: 4.0)
  9. let plusMinusVector = firstVector +- secondVector
  10. // plusMinusVector is a Vector2D instance with values of (4.0, -2.0)


この演算子は、2つのベクトルの x の値を一緒に加算し、第1のものから第2のベクトルの y 値を減算します。それは本質的に "加算的" 演算子のため、+- などの加算的挿入辞演算子と同じ優先順位グループが与えられます。演算子優先グループと結合性の設定の完全なリストを含む、Swift 標準ライブラリが提供する演算子については、演算子の宣言 を参照してください。優先グループの詳細および独自の演算子および優先グループを定義する構文については、演算子の宣言 を参照してください。


注意: 接頭辞または接尾辞演算子を定義するときには、優先順位を指定しないでください。しかし、同じオペランドに接頭辞と接尾辞演算子の両方を適用する場合は、接尾辞演算子の方が最初に適用されます。





前:アクセス制御 次:言語リファレンスについて
目次
Xcode 9 の新機能

Swift:はじめに
Swift と Cocoa と Objective-C
Swift Blog より

  • ようこそ Swift へ(Part I)
  • Swift について
  • バージョン互換性
  • Swift のツアー
  • 単純な値
    制御フロー
    関数とクロージャ
    オブジェクトとクラス
    列挙型と構造体
    プロトコルと拡張機能
    エラー処理
    汎用(ジェネリック)
  • Swift 言語のガイド(Part II)
  • Swift の基本
  • 定数と変数
  • 定数と変数の宣言
    型注釈
    定数と変数の命名
    定数と変数の印刷
    コメント
    セミコロン
  • 整数
  • 整数の境界
    Int
    UInt
    浮動小数点数
    安全な型と型推論
    数値リテラル
  • 数値型変換
  • 整数変換
    整数と浮動小数点間の変換
    型エイリアス
    ブール型
    タプル
  • Optional
  • nil
    if 文と強制開封
    Optional の結合
    暗黙に開封された Optionals
    エラー処理
  • アサーション(断言)と前提条件
  • アサーションを使用したデバッグ
    前提条件の実施
  • 基本演算子
  • 専門用語
    代入演算子
  • 算術演算子
  • 剰余演算子
    単項マイナス演算子
    単項プラス演算子
    複合代入演算子
    比較演算子
    三項条件演算子
    Nil 合体演算子
  • 範囲演算子
  • 閉鎖範囲演算子
    半開放範囲演算子
    片方の範囲
  • 論理演算子
  • 論理 NOT 演算子
    論理 AND 演算子
    論理 OR 演算子
    論理演算子の組み合わせ
    明示的な括弧
  • 文字列と文字
  • 文字列リテラル
    複数行の文字列リテラル
    文字列リテラル内の特殊文字
    空の文字列の初期化
    文字列の可変性
    文字列は値の型
    文字を使った作業
    文字列と文字を連結
    文字列補間
  • ユニコード(Unicode)
  • Unicode スカラー
    文字列リテラルの中の特別の文字
    拡張書記クラスタ
    文字を数える
  • 文字列のアクセスと変更
  • 文字列のインデックス
    部分文字列
    挿入と削除
  • 文字列の比較
  • 文字列と文字の等価性
    接頭辞と接尾辞の等価性
  • 文字列の Unicode 表現
  • UTF-8 の表現
    UTF-16 表現
    Unicode のスカラー表現
  • コレクション型
  • コレクションの可変性
  • 配列
  • 配列型省略構文
    空の配列の作成
    デフォルト値を持つ配列の作成
    2つの配列を共にして一つの配列に
    配列リテラルでの配列の作成
    配列へのアクセスと変更
    配列の繰り返し処理
  • セット
  • セット型のハッシュ値
    セット型の構文
    空のセットの作成と初期化
    配列リテラルでセットの作成
    セットへのアクセスと変更
    セットを反復処理
  • セット操作の実行
  • 基本的なセットの操作
    セットの身分と等価性
  • Dictionary
  • Dictionary 型の省略型構文
    空の Dictionary を作成
    Dictionary リテラルで Dictionary の作成
    Dictionary のアクセスと変更
    Dictionary を繰り返し処理
  • フロー制御
  • For-In ループ
  • While ループ
  • While
    Repeat-While
  • 条件文
  • if 文
  • Switch
  • 暗黙の Fallthrough なし
    範囲の一致
    タプル(Tuples)
    値の結合
    Where
    複合した case
  • 制御転送文
  • Continue
  • Break
  • ループ文内の Break
    Switch 文内の Break
    Fallthrough
    ラベル付きの文
    早期終了
    API 利用可能性の確認
  • 関数
  • 関数の定義と呼び出し
  • 関数のパラメータと戻り値
  • パラメータなしの関数
    複数パラメータの関数
    戻り値なしの関数
    複数の戻り値を持つ関数
    optional のタプル型の戻り値
  • 関数引数のラベルとパラメータ名
  • 引数のラベルの指定
    引数ラベルの省略
    デフォルトのパラメータ値
    可変個引数のパラメータ
    In-Out パラメータ
  • 関数型
  • 関数型の使用
    パラメータ型としての関数型
    戻り値の型としての関数型
    入れ子になった関数
  • クロージャ
  • クロージャ式
  • ソートするメソッド
    クロージャ式の構文
    文脈から型を推論
    単一式クロージャからの暗黙的戻り値
    引数名の省略
    演算子メソッド
    後続クロージャ
    値のキャプチャ
    クロージャは参照型
    クロージャのエスケープ
    オートクロージャ
  • 列挙型
  • 列挙型の構文
    switch 文で列挙型の値の一致
    関連する値
  • 生の値
  • 暗黙に割り当てられた生の値
    生の値からの初期化
    再帰的な列挙型
  • クラスと構造体
  • クラスと構造体を比較
  • 定義の構文
    クラスと構造体のインスタンス
    プロパティにアクセス
    構造体型のためのメンバー化イニシャライザ
    構造体と列挙型は値型
  • クラスは参照型
  • ID 演算子
    ポインタ
    クラスと構造体の間の選択
    文字列、配列、辞書の代入とコピーの動作
  • プロパティ
  • 格納されたプロパティ
  • 定数構造体インスタンスの格納されたプロパティ
    遅延した格納されたプロパティ
    格納されたプロパティとインスタンス変数
  • 計算されたプロパティ
  • セッタ宣言の省略形
    読み取り専用の計算されたプロパティ
    プロパティ監視者
    グローバルとローカル変数
  • 型プロパティ
  • 型プロパティの構文
    型プロパティの照会と設定
  • メソッド
  • インスタンスメソッド
  • self プロパティ
    インスタンスメソッド内から値の型を変更
    変異メソッド内で self に代入
    型メソッド
  • サブスクリプト
  • サブスクリプトの構文
    サブスクリプトの使用法
    サブスクリプトのオプション
  • 継承
  • 基本クラスの定義
    サブクラス化
  • オーバーライド(上書き)
  • スーパークラスメソッド、プロパティ、サブスクリプトへのアクセス
    オーバーライドするメソッド
  • オーバーライドするプロパティ
  • プロパティのゲッタとセッタのオーバーライド
    プロパティ監視者のオーバーライド
    オーバーライドの防止
  • 初期化
  • 格納されたプロパティの初期値を設定
  • イニシャライザ
    デフォルトのプロパティ値
  • 初期化のカスタマイズ
  • 初期化パラメータ
    パラメータ名と引数ラベル
    引数ラベルのないイニシャライザのパラメータ
    Optional のプロパティ型
    初期化中に定数プロパティへの代入
  • デフォルトのイニシャライザ
  • 構造体型のためのメンバ化イニシャライザ
    値型のイニシャライザデリゲート
  • クラスの継承と初期化
  • 指定イニシャライザとコンビニエンスイニシャライザ
    指定とコンビニエンスイニシャライザの構文
    クラス型のイニシャライザデリゲート
    二相の初期化
    イニシャライザ継承とオーバーライド
    自動イニシャライザの継承
    実際の指定とコンビニエンスイニシャライザ
  • 失敗可能イニシャライザ
  • 生の値を持つ列挙型のための失敗可能イニシャライザ
    初期化失敗の伝播
    失敗可能イニシャライザのオーバーライド
    init! の失敗可能イニシャライザ
    必須イニシャライザ
    クロージャや関数でのデフォルトのプロパティ値設定
  • デイニシャライザ
  • デイニシャライザはどのように働くか
    作動中のデイニシャライザ
  • Optional の連鎖
  • 強制開封の代替としての Optional の連鎖
    Optional の連鎖のモデルクラスの定義
    Optional の連鎖を使用したプロパティへのアクセス
    Optional の連鎖を通じてメソッドを呼び出す
  • Optional の連鎖を通じてサブスクリプトへのアクセス
  • Optional 型のサブスクリプトにアクセス
    連鎖の複数レベルのリンク
    optional の戻り値を持つメソッドでの連鎖
  • エラー処理
  • エラーの表現と Throw
    エラーの処理
    throw 関数を使用したエラーの伝播
    Do-Catch を使用したエラー処理
    エラー をOptional の値に変換
    エラー伝播を無効に
    クリーンアップアクションの指定
  • 型キャスト
  • 型キャストのためのクラス階層の定義
    型のチェック
    ダウンキャスト
  • Any と AnyObjecgt 用の型キャスティング
  • ネストした型
  • 実際のネストした型
    ネストした型への参照
  • 拡張機能
  • 拡張機能の構文
    計算されたプロパティ
    イニシャライザ
  • メソッド
  • 変異インスタンスメソッド
    サブスクリプト
    ネストした型
  • プロトコル
  • プロトコルの構文
    プロパティの要件
    メソッドの要件
    変異メソッドの要件
  • イニシャライザの要件
  • プロトコルイニシャライザ要件のクラス実装
    失敗可能イニシャライザの要件
    型としてのプロトコル
    デリゲート
  • 拡張機能を持つプロトコル準拠の追加
  • 拡張機能を持つプロトコルの採用を宣言
    プロトコル型のコレクション
    プロトコルの継承
    クラス専用プロトコル
    プロトコルの構成
    プロトコル準拠の確認
    Optional のプロトコル要件
  • プロトコル拡張機能
  • デフォルトの実装の提供
    プロトコル拡張機能に制約を追加
  • ジェネリック(汎用)
  • 汎用が解決する問題
    汎用関数
    型パラメータ
    型パラメータの命名
    汎用の型
    汎用型の拡張
  • 型の制約
  • 型制約の構文
    実際の型の制約
  • 関連型
  • 実際の関連型
    既存の型を拡張して関連型を指定
    型注釈を使用して関連型を制約
    汎用の Where 句
    汎用の Where 句を含む拡張機能
    関連する型と汎用の Where 句
    汎用のサブスクリプト
  • 自動参照カウント
  • どのように ARC は働くか
    実際の ARC
    クラスインスタンス間の強い循環参照
  • クラスインスタンス間の強い循環参照の解決
  • 弱い参照
    所有されていない参照
    所有されていない参照と暗黙に開封された Optional のプロパティ
    クロージャの strong な循環参照
  • クロージャの strong な循環参照の解決
  • キャプチャリストの定義
    弱い参照と所有されていない参照
  • メモリの安全性
  • メモリへのアクセス競合の理解
    メモリアクセスの特徴
    In-Out パラメータへのアクセスの競合
    メソッド内の Self へのアクセスの競合
    プロパティへのアクセスの競合
  • アクセス制御
  • モジュールとソースファイル
  • アクセスレベル
  • アクセスレベルの全体的指針
    デフォルトのアクセスレベル
    ターゲット一つのアプリのアクセスレベル
    フレームワークのアクセスレベル
    ユニットテストのターゲット用のアクセスレベル
    アクセス制御の構文
  • カスタム型
  • タプル型
    関数型
  • 列挙型
  • 生の値と関連する値
    ネストした型
    サブクラス化
  • 定数、変数、プロパティ、およびサブスクリプト
  • ゲッタとセッタ
  • イニシャライザ
  • デフォルトのイニシャライザ
    構造体型用のデフォルトメンバ化イニシャライザ
  • プロトコル
  • プロトコルの継承
    プロトコルの準拠
  • 拡張機能
  • 拡張機能の private メンバ
    汎用
    型エイリアス
  • 高度な演算子
  • ビット単位演算子
  • ビット単位の NOT 演算子
    ビット単位の AND 演算子
    ビット単位の OR 演算子
    ビット単位の XOR 演算子
  • ビット単位の左と右シフト演算子
  • 符号なし整数のシフト動作
    符号付き整数のシフト動作
  • オーバーフロー演算子
  • 値オーバーフロー
    優先順位と結合性
  • 演算子メソッド
  • 接頭辞と接尾辞演算子
    複合代入演算子
    等価演算子
  • カスタム演算子
  • カスタム挿入辞演算子の優先順位
  • 言語のガイド(Part III)
  • 言語リファレンスについて
  • 文法の読み方
  • 語彙の構造
  • 空白とコメント
    識別子
    キーワードと句読点
  • リテラル
  • 整数リテラル
    浮動小数点リテラル
    文字列のリテラル
    演算子

  • 型注釈
    型識別子
    タプル型
    関数型
    エスケープしないクロージャの制限事項
    配列型
    辞書型
    Optional の型
    暗黙に開封された Optional の型
    プロトコル構成の型
    メタタイプ型
    型の継承句
    型の推測

  • 接頭辞式
    Try 演算子
  • 二項式
  • 代入演算子
    三項条件演算子
    型キャスト演算子
  • 一次式
  • リテラル式
    Self 式
    スーパークラス式
  • クロージャ式
  • キャプチャ・リスト
    暗黙のメンバ式
    括弧で囲まれた式
    タプル式
    ワイルドカード式
    キーパス式
    セレクタ式
    キーパス文字列式
  • 接尾辞の式
  • 関数呼び出し式
    イニシャライザ式
    明示的なメンバ式
    接尾辞の Self 式
    サブスクリプト 式
    強制値の式
    Optional の連鎖式

  • ループ文
  • For-In 文
    While 文
    Repeat-While 文
  • 分岐文
  • if 文
    Guard 文
  • switch 文
  • switch 文は、網羅的である必要あり
    実行が暗黙的に case を Fall Through しない
    ラベル付き文
  • 制御転送文
  • break 文
    continue 文
    fallthrough 文
    return 文
    throw 文
    defer 文
    do 文
  • コンパイラ制御文
  • 条件コンパイルブロック
    行制御文
    利用可能条件
  • 宣言
  • トップレベルのコード
    コードブロック
    Import 宣言
    ­定数の宣言
  • 変数の宣言
  • 格納された変数と格納された変数のプロパティ
    計算された変数と計算されたプロパティ
    格納された変数監視者とプロパティの監視者
    型変数プロパティ
    型エイリアス宣言
  • 関数の宣言
  • パラメータ名
    In-Out パラメータ
    パラメータの特殊な種類
    メソッドの特殊な種類
    Throw する関数とメソッド
    Rethrow する関数とメソッド
    決して返さない関数
  • 列挙型の宣言
  • 任意の型の case を列挙
  • 間接による列挙
    生の値型の case を列挙
    列挙型 case へのアクセス
    構造体の宣言
    クラスの宣言
  • プロトコルの宣言
  • プロトコル・プロパティ宣言
    プロトコル・メソッド宣言
    プロトコル・イニシャライザ宣言
    プロトコル・サブスクリプト宣言
    プロトコルに関連した型の宣言
  • イニシャライザ宣言
  • 失敗可能イニシャライザ
    デイニシャライザ宣言
    拡張機能の宣言
    サブスクリプト宣言
    演算子の宣言
    優先順位グループ宣言
  • 宣言修飾子
  • アクセス制御レベル
  • 属性
  • 宣言の属性
  • インターフェイスビルダーで使われる宣言属性
    型の属性
  • パターン
  • ワイルドカードパターン
    識別子パターン
    値結合パターン
    タプルパターン
    列挙型 case パターン
    Optional のパターン
    型キャストパターン
    式のパターン
  • 汎用パラメータと引数
  • 汎用パラメータ句
  • 汎用の where 句
    汎用引数句
  • 文法のまとめ
  • 語彙の構造



    宣言
    属性
    パターン
    汎用パラメータと引数
  • マニュアルの変更履歴
  • 変更履歴












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)












    トップへ(Swift Language Basics)