読者です 読者をやめる 読者になる 読者になる

Codable Tech Blog

CodableがiOSプログラミング、クライアントサイド(JavaScript)・サーバーサイド(Java,C#,PHP)プログラミング、その他技術(MySQL、Linuxなど)について発信しています

MENU

Swift 条件分岐・if文・switch文

swift

プログラムは単純に順番に処理を実行するだけでなく、ある変数の値がAであればこの処理を実行して、値がBの時はこっちの処理を実行する、といった形で処理を分岐させることができます。
Swiftでは処理を分岐させるための命令としてif文、switch文が用意されています。

if文

ある条件式を設定し、その条件式が成り立つか、成り立たないかで処理を場合分けするのがif文です。siwftでのif文の構文は次のようになります。

if 条件式 {
    条件式が成り立った場合の処理を記述
}


条件式にはBool型の値を指定します。
falseであれば条件が不成立、trueであれば条件が成立したと判断されます。

条件式がtrueの場合、条件が成立しますのでifブロックの中のprint文が実行され、true!!という文字がコンソールに出力されます。条件式がfalseの場合、条件が不成立ですのでifブロックの中の処理は実行されません。

比較演算子

if文を利用する時、単純にtrueとfalseを指定して処理を分岐させるだけではあまり使い道がありません。Swiftでは比較演算子と呼ばれる演算子があります。これは2つの値を比較し、比較結果に応じてtrueもしくはfalseを算出する演算子です。比較演算子には次のものがあります。

演算子 説明
a == b aとbが等しければtrue、等しくなければfalse
a != b aとbが等しくなければtrue、等しければfalse
a > b aがbより大きければtrue、aとbが等しい、もしくはaがbより小さければfalse
a < b aがbより小さければtrue、aとbが等しい、もしくはaがbより大きければfalse
a >= b aとbが等しい、もしくはaがbより大きければtrue、aがbより小さければfalse
a <= b aとbが等しい、aがbより小さければtrue、aがbより大きければfalse


この例ではnumの値が15ですのでnum > 10の条件式が成立し、「numは10より大きい」という文字列がコンソールに出力されます。しかし、num < 10の条件式は成立しませんので、「numは10より小さい」という文字列は出力されません。

論理演算子

値の比較を行うとき、複数の条件式を組み合わせたいことがよくあります。
たとえば、「ある数が10以上かつ20以下であれば条件を満たす」といった条件式を指定したい時です。そういった時に以下の論理演算子を利用することで、複数の条件式を組み合わせた条件式を作成することができます。

演算子 説明
条件式1 && 条件式2 条件1と条件2の両方が成り立てばtrue、一方でも成り立たなければfalse
条件式1 || 条件式2 条件1と条件2の一方が成り立てばtrue、両方とも成り立たなければfalse

それぞれの構文は次のようになります。

if 条件式1 && 条件式2 {
    条件式1と条件式2が成り立った場合の処理を記述
}
if 条件式1 || 条件式2  {
    条件式1と条件式2のいずれかが成り立った場合の処理を記述
}

また、「ある数が10以上かつ20以下でない」という否定条件を指定したい時にも論理演算子を利用します。

演算子 説明
!条件式 条件がtrueであればfalseになり、条件がfalseであればtrueになる

論理演算子&&と!を使用した例が以下です。

変数num1は値が15であるため、num1が10以上かつ20以下という条件を満たすため、「num1は10以上、20以下である」という文字列がコンソールに出力されます。変数num2は値が5であるため、num2が10以上かつ20以下であるという条件を満たしません。しかし、論理演算子!が条件式に
ついているため、結果が反転(falseがtrueになる)します。この結果、「num2は10以上、20以下ではない」という文字列もコンソールに出力されます。

場合分け

条件に一致した場合だけでなく、条件に一致しなかった場合にも処理を記述したい場合、else句を利用します。if-else文の構文は次のようになります。

if 条件式 {
    条件式が成り立った場合の処理を記述
}else{
    条件式が成り立たなかった場合の処理を記述
}

if-else文の例は次の通りです。

この場合、if文の条件式「vale < 10」を満たさず、結果はfalseになります。if文の条件の値がfalseになった時、else句のブロックに記述されている文が実行されますので「valueは10以上」という文字列がコンソールに出力されます。

if-else文は2つの場合分けでした。さらに3つ、4つと場合分けを増やしたい場合、else if句を追加します。if-else if-else文の構文は次の通りです。

if 条件式1 {
    条件式1が成り立った場合の処理を記述
}else if 条件式2{
    条件式2が成り立った場合の処理を記述
}else{
    条件式が成り立たなかった場合の処理を記述
}

ある変数の値を3パターンで場合分けした例を次に示します。

この例では、numの値が10の場合、numの値が11から20の間の場合、numの値がそれ以外の場合の3通りで場合分けしています。このように、else if句を使うことで3つ以上の場合分けに対応した条件分岐を実現することができます。
なお、if-else if-else文においてelse句はオプションですので不要であれば、else句を削除してもかまいません。

switch文

if文を利用した場合分けの処理の中で、変数もしくは定数がどの値とマッチしているかを判断して処理を切り分けることがよく行われます。次のif文はnumの値がある値とマッチしていれば、printlnで文字列を出力し、いずれもマッチしなければ、マッチしなかった旨を出力します。

値のマッチングによる分岐処理をif-else if-else文で記述しても問題ありませんが、switch文を利用することでより読みやすいコードを記述することが可能になります。
switch文の書式は以下の通りです。

switch マッチング対象の変数or定数 {
case1:1
case2:2
default:3
}

switch文ではマッチング対象の変数とcase句に記述されている値の比較を行い、最初にマッチした箇所のcase句の処理が実行されます。また、switch文は網羅的である必要があります。これはswitch文で値の比較を行った時、必ずいずれかの文が実行されなければいけないということです。このため、switch文ではdefault句が用意されており、case句に記述したいずれの条件とも合致しない場合はdefault句の処理が実行されます。default句はswitchの末尾に書きます。先ほど記述したif-else if-else文をswitch文で書き直すと以下のようになります。

numの値が20ですので、case 20とマッチし、case 20:句の処理が実行されます。swiftのswitch文は1つのcaseを実行した後、switch文のブロックを抜けますので今回の例では「20と一致」という文言を出力してswitch文を抜けます。

case句の注意点

それぞれのcaseは実行コードを1つは含んでいないといけません。次の例は不正な記述です。なぜなら最初のケース(case num 10:)に実行コードが記述されていないからです。

もし、複数のケースで同じ処理を行いたい場合、カンマ区切りで値を並べましょう。

このように記述した場合、numの値が10もしくは20の場合は「 10または20と一致」という文字列が出力されます。

範囲マッチング

switch文では単独の値の比較だけではなく、ある値が特定の範囲内に収まっているかどうかも判定できます。if文ではand演算子を用いて特定の範囲内かどうかを判定する処理が記述できます。switch文では範囲演算子を利用してより簡潔に表現することができます。

範囲演算子

演算子 説明
a...b aからbまで。aはbより小さい値でなければならない。
a..<b aからb-1まで。aはbより小さい値でなければならない。

この範囲演算子を活用することで、範囲による場合分け処理を簡潔に記述できます。switch文を利用した範囲による場合分け処理は以下のように記述できます。

この例では範囲演算子...を利用してnumの値がどの範囲に含まれるかを判断しています。numの値が0から10の間であれば、case 0...10:句の処理が実行されますし、numの値が11から30の間であれば、case 11...30:句の処理が実行されます。今回はnumの値は55なのでcase 31...60:句の処理が実行されます。

タプルのマッチング

switch文ではタプルのマッチング判定を行うことも可能です。タプルのそれぞれの要素に対して、値もしくは範囲指定によるマッチングを行うことができます。もし、全ての値と合致させたい場合は_を使います。_は「ワイルドカードパターン」と呼ばれる識別子で全ての値とマッチングする特別な識別子です。

case (0, 0)は1番目の要素が0、2番目の要素が0の時、マッチするcase句になります。case (_, 0)は1番目の要素は不問なので、2番目の要素が0であれば、マッチするcase句になります。case (0, _)は2番目の要素は不問なので、1番目の要素が0であれば、マッチするcase句になります。case (-2...2, -2...2)は1番目の要素が-2から2の範囲、2番目の要素が-2から2の範囲の時、マッチするcase句になります。今回のケースではnTapleが(1, 1)なのでcase (-2...2, -2...2)に合致します。
このため、case (-2...2, -2...2)の文が出力されます。

バリューバインディング(Value Binding)

switch文ではマッチした値をcase句の中で、変数や定数として利用することができます。このように外部で定義された値を取り込むことをバリューバインディングと呼びます。次の例では、switch文の外で定義されたnTapleの値をswitchブロックの中に取り込んでいます。

case (let x, 0)は2番目の要素が0だった場合に合致するcase句です。この条件に合致した場合、バリューバインディングを利用してnTapleの1番目の要素の値を定数xとして取り込みます。
case (0, let y)は1番目の要素が0だった場合に合致するcase句です。この条件に合致した場合、バリューバインディングを利用してnTapleの2番目の要素の値を定数yとして取り込みます。
case let (x, y)はどの条件でも合致するcase句です。このため、このswitch文ではdefault句が不要です。この場合、nTapleの1番目の要素の値を定数x、2番目の要素の値を定数yとして取り込みます。今回の例ではcase句の中で値を変更しないのでletを使用してますがcase句の中で値を変更したい場合はvarを利用します。バリューバインディングで取り込んだ変数および定数はswitch文の中でだけ有効であることに注意してください。

Where句

バリューバインディングによって取り込んだ値を利用して、case句の中で条件式を記述することができます。case句の中で条件式を記述するときに利用するのがwhere句です。where句を利用することによってcase句の中で条件を記述することができます。
構文は以下の通りです。

switch マッチング対象の変数 {
case バリューバインディング where 条件式1:1
case バリューバインディング where 条件式2:2
case バリューバインディング
    文3
}

次の例はバリューバインディングを利用して、switchブロックに値を取り込みつつ、条件判定も行うswitch文です。

case let (x, y) where x == yは1番目の要素と2番目の要素が同じ場合に合致するcase句です。
case let (x, y) where x == -yは1番目の要素が2番目の要素に-1を掛けた数と同じである場合に合致するcase句です。case let (x, y)はどの条件でも合致するcase句です。この場合、yetAnotherPointが(1, -1)ですので、case let (x, y) where x == -yに該当します。このようにバリューバインディングで取り込んだ値とwhere句を利用することでcase句の中で条件式を記述することが可能です。