Swift 6.0 beta 日本語化計画 : Swift 6.0 beta
基本演算子
operator(演算子) は、値の確認、変更、または組み合わせるために使用する特殊記号又はフレーズです。たとえば、加算演算子(+)は、let i = 1 + 2 のように2つの数値を加算し、論理 AND 演算子(&&) は、if enteredDoorCode && passedRetinaScan のように、2つのブール値を組み合わせます。
Swift は、C などの言語で既におなじみの演算子をサポートし、いくつかの機能を改善して、一般的なコーディングエラーを排除します。代入演算子(=) は、等価演算子(==) が意図されたときに誤って使用される事を防ぐために、値を返しません。算術演算子(+、 - 、*、/、% など) は、それらを保存できる型の許容値の範囲より大きくなったり小さくなった数字を扱うとき、予期しない結果を回避するために、値のオーバーフローを検知して禁止します。オーバーフロー演算子 で説明するように、Swift のオーバーフロー演算子を使用して値のオーバーフロー動作を選択することができます。
Swift にはまた、C には見られない範囲演算子 (a..<b 及び a...b) を、値の範囲を表現するためのショートカットとして用意されています。
この章では、Swift の一般演算子について説明します。高度な演算子 では、Swift の高度な演算子をカバーし、独自のカスタム演算子を定義し、独自のカスタム型の標準演算子を実装する方法について説明します。
演算子は、単項、二項、または三項のいずれかに分類されます。
演算子が影響する値が オペランド です。式 1 + 2 では、+ 記号は、中置演算子であり、その2つのオペランドは値 1 と 2 です。
代入演算子 (a = b) は b の値で a の値を初期化するか更新します。
代入の右側に複数の値を持つタプルがある場合、その要素は、一度に複数の定数または変数に分解されます。
C 言語や Objective-C の代入演算子とは異なり、Swift の代入演算子は、それ自体値を返しません。以下の文は有効ではありません:
この機能は、等価演算子(==) が実際に意図されたときに、間違って代入演算子(=) が使用される事を防ぐことができます。if x = y を無効にすることで、Swift は、コード内のこれらの種類のエラーを避けるのを助けます。
Swift は、すべての数値型に対し4つの標準 算術演算子 をサポートしています。
C や Objective-C の算術演算子とは異なり、Swift の算術演算子は、デフォルトでは値がオーバーフローすることを許していません。Swift のオーバーフロー演算子(a &+ b のような) を使用して値のオーバーフローの動作を選択できます。オーバーフロー演算子 を参照してください。
加算演算子は、String の連結もサポートしています。
剰余演算子 (a % b)は、b の何倍の数が a の内輪に収まるかを示し、(剰余 として知られている) 残った値を返します。
剰余演算子がどのように機能するかをここに示します。9 % 4 を計算するには、まず 9 の内輪にどれだけ多くの 4 がうまく収まるかを計算します:
9 の内輪に 2つの 4 を収めることができ、剰余は(オレンジ色で示すように) 1 です。
Swift では、これはこのように書くことになります。
a % b の答えを決定するには、% 演算子は、次の式を計算し、その出力として 剰余(remainder) を返します。
a =(b × some multiplier) + remainder
ここで some multiplier は、a の内輪に収まる b の倍数の最大数です。
この式に 9 と 4 を入れると、こうなります:
9 = (4 × 2) + 1
a が負の値の時、剰余を計算するときに、同じメソッドが適用されます。
上記の式に -9 および 4 を挿入すると、こうなります:
-9 =(4×-2)+-1
剰余の値として -1 を与えます。
b の符号は b が負の値の場合は無視されます。これは a % b と a % -b が常に同じ答えを与えることを意味します。
数値の符号は、- を数値の前に使用して切り替えることができ 、単項マイナス演算子 として知られています:
単項マイナス演算子(-) は空白なしに、それが動作する値の直前に付加します。
単項プラス演算子(+)は、単にそれが動作した値をそのまま変更なしに返します。
単項プラス演算子は、実際には何もしませんが、負の数値用の単項マイナス演算子も使用した場合、正の数用にあなたのコード内で対称性を提供するためにそれを使用できます。
C と同様に、Swift は代入(=)と別の操作を組み合わせた、複合代入演算子 を提供します。一つの例は、加算代入演算子(+=)です。
式 a += 2 は、 a = a + 2 の省略形です。効果的には、加算と代入が一つの演算子に結合され、同時に両方の演算を実行します。
Swift 標準ライブラリで提供される演算子については、演算子の宣言 で述べます。
Swift は、以下の比較演算子をサポートしています。
それぞれの比較演算子は、文が真であるかどうかを示す Bool 値を返します。
比較演算子は、多くの場合、if 文などの条件文で使用されます。
if 文の詳細については、フロー制御を参照してください。
同じ型と同じ数値を持つ 2 つのタプルを比較することができます。タプルは、左から右に、一度に 1 つの値を比較して、等しくない 2 つの値が見つかるまで比較されます。これらの 2 つの値は比較され、その比較の結果がタプル比較の全体的な結果を決定します。すべての要素が等しい場合、タプル自体も等しいです。例えば:
上に挙げた例では、左から右への比較動作を最初の行で確認できます。1 が 2 より小さいため、タプル内の他の値に関係なく、(1,"zebra") は (2,"apple") よりも小さいとみなされます。比較が既にタプルの最初の要素によって決定されているので、"zebra" が "apple" より小さくなくても関係ありません。ただし、タプルの最初の要素が同じ場合、2 番目の要素が比較 されます。これが、2 行目と 3 行目で起こっている事です。
タプルは、演算子がそれぞれのタプル内の各値に適用できる場合のみ、与えられた演算子で比較できます。たとえば、以下のコードで示すように、String 型と Int 型の両方の値が < 演算子を使用して比較できるため、(String、Int) の型の 2 つのタプルを比較できます。対照的に、< 演算子は Bool 値に適用できないため、(String、Bool) 型の 2 つのタプルは < 演算子で比較できません。
三項条件演算子 は、question ? answer1:answer2 の形式を取る、三つの部分から成る特別な演算子です。それは question が真か偽かに基づいて2つの式のいずれか一つを評価するための省略形です。question が true の場合、それは answer1 を評価し、その値を返します。それ以外の場合は、answer2 を評価し、その値を返します。
三項条件演算子は、以下のコードの省略形です。
ここで、表の行の高さを計算する例を挙げましょう。行の高さは、ヘッダがある場合、コンテンツの高さよりも 50 ポイント高く、ヘッダがない場合、行の高さは 20 ポイント高くなります。
上の例は、以下のコードの省略形です。
最初の例の三項条件演算子の使用は、rowHeight を 1 行のコードで正しい値に設定できることを意味し、これは、2 番目の例で使用されるコードよりも簡潔です。
三項条件演算子は、考慮すべき2つの式を決定するための効率的な省略形を提供します。しかし、注意して三項条件演算子を使用してください。過剰に使用すると、その簡潔さは、読みにくいコードにつながります。1つの複合文に三項条件演算子の複数のインスタンスを組み合わせることは避けてください。
nil 合体演算子 (a ?? b) は、optional a が値を含んでいる場合それを開封するか、または a が nil の場合、デフォルトの b の値を返します。式 a は、常に optional の型です。式 b は、a の内部に保存されている型と一致しなければなりません。
nil 合体演算子は、以下のコードの省略形です。
上記のコードは、三項条件演算子を使用し、a が nil でないときに a の内側に包まれた値にアクセスするのに、強制開封(a!)を使用し、そうでなければ b を返します。nil 合体演算子は、簡潔で読みやすい形式でこの条件のチェックと開封をカプセル化するためのよりエレガントな方法を提供します。
以下の例では、デフォルトの色名と optional のユーザー定義の色名のどちらかを選択する nil 合体演算子を使用しています。
userDefinedColorName 変数は nil のデフォルト値を持ち、optional の String として定義されています。 userDefinedColorName は optional 型であるため、その値を考慮するために nil 合体演算子を使用できます。上記の例では、colorNameToUse と呼ばれる String 変数の初期値を決定するために演算子が使用されています。 userDefinedColorName は nil なので、式 userDefinedColorName ?? defaultColorName は defaultColorName の値、つまり "red" を返します。
userDefinedColorName に、nil でない値を代入し、もう一度 nil 合体演算子チェックを実行した場合、userDefinedColorName 内に包まれた値が、デフォルトの代わりに使用されます。
Swift は、値の範囲を表現するための省略形であるいくつかの 範囲演算子 を含んでいます。
閉鎖範囲演算子 (a...b)は a から b に至る範囲を定義し、値 a と b を含みます。a の値は b より大きくてはいけません。
閉鎖範囲演算子は、for-in ループなどと同様に、使用されるすべての値の範囲を反復処理する時に便利です。
for-in ループの詳細については、フロー制御 を参照してください。
半開放範囲演算子(a..<b) は a から b に至る範囲を定義しますが、b を含みません。それは、その最後の値を含まず、その最初の値を含んでいるので、半開放 であると呼ばれます。閉鎖範囲演算子と同じように、a の値は b より大きくてはいけません。a の値が b に等しい場合、結果の範囲は空になります。
半開放範囲は、リストの(それを含まない) 長さまでカウントする時に有用で、配列などのゼロベースのリストを操作するときに特に有用です:
それは半開放範囲であるため、配列は4つの項目を含んでいることに注意し、0..<count は、3 (配列の最後の項目の指標)までしかカウントしません。配列の詳細については、配列 を参照してください。
閉鎖範囲演算子には、ある方向で可能な限り継続する範囲 (たとえば、指標 2 から配列の終わりまでのすべての要素を含む範囲) の代替形式があります。このような場合、範囲演算子の片方から値を省略できます。このような範囲は演算子には片方だけに値があるため 片方の範囲 と呼ばれます。例えば:
半開放範囲演算子にも、その最後の値のみで書かれた片方の書式があります。両側に値を含めるのと同じように、最後の値は範囲の一部ではありません。例えば:
片方の範囲は、サブスクリプトだけでなく、他のコンテキストでも使用できます。最初の値を省略した片方の範囲を反復処理することはできません。なぜなら、繰り返しの開始場所が明確でないためです。最後の値を省略した片方の範囲で反復処理を行うことが できます。ただし、範囲が無限に続くので、ループの明示的な終了条件を追加してください。以下のコードに示すように、片方の範囲に特定の値が含まれているかどうかを確認することもできます。
論理演算子 は、ブール論理値の true と false の変更または結合をします。Swift は C ベースの言語に見られる3つの標準的な論理演算子をサポートしています。
論理 NOT 演算子 (!a)は、true が false になり、false が true になるようにブール値を反転します。
論理 NOT 演算子は前置演算子であり、空白なしで、それが操作する値の直前に表示されます。それは以下の例のように、"not a"と読むことができます:
if !allowedEntry のフレーズは、"もしエントリが許されてなかったら" のように読むことができます。"エントリが許されていない"が true の場合にのみ、後続の行が実行されます:すなわち、allowesEntry が false の場合に。
この例のように、ブール定数と変数の名を慎重に選択すると、二重否定または論理文を混乱させる事を回避しながら、読みやすく簡潔なコードを維持するのを助けます。
論理 AND 演算子 (a && b) は式全体も true になるためには、両方の値が true でなければならない論理式を作成します。
どちらかの値が false の場合、式全体も false になります。事実、最初 の値が false の場合、全体の式は true とならないので、第2の値は、評価すらされません。これは、短絡評価 として知られています。
以下の例は、2つの Bool 値を考慮し、両方の値が true である場合にのみアクセスを許可します:
論理 OR 演算子(a || b)は、二つの隣接するパイプ文字から作られた中置演算子です。2つの値の 一方 のみが true であれば式全体が true となる論理式を作成するためにそれを使用できます。
上記の論理 AND 演算子と同様に、論理 OR 演算子は、その式を検討する短絡評価を使用します。論理 OR 式の左辺が true であれば、式全体の結果を変更することはできないので、右辺は、評価されません。
以下の例では、最初の Bool 値 (hasDoorKey) は false ですが、2番目の値(knowsOverridePassword) が true です。一つの値が true であるため、式全体も true に評価され、アクセスが許可されます。
複数の論理演算子を組み合わせて長い複合式を作成できます。
この例では、長い複合式を作成するために、複数の && と || 演算子を使用しています。ただし、&& と || 演算子は、2つの値を操作するだけなので、これは実際には互いに連鎖する3つの小さい式です。この例は以下のように読むことができます:
我々は正しいドアのコードを入力し、網膜スキャンに合格したか、または有効なドアの鍵を持っているか、または緊急オーバーライドパスワードを知っている場合、アクセスを許可されます。
enteredDoorCode、passedRetinaScan、および hasDoorKey の値に基づいて、最初の二つの部分式は false です。ただし、緊急オーバーライドパスワードを知っているので、全体的な複合式は、依然として true と評価されます。
複合式の意図を読みやすくするために、厳密に言えば必要でない括弧を含めることが便利な場合があります。上記のドアアクセスの例では、その意図を明示的にするために複合式の最初の部分の周りに括弧を追加するのが便利です。
括弧は、最初の2つの値が、全体的な論理では可能ならば分けられる一部の状態とみなされることを明らかにします。複合式の出力は変化しませんが、全体的な意図は、読者へより明確に伝わります。読みやすさは常に短かさよりも好ましく、意図を明確にするのに役立つ所に括弧を使用して下さい。