条件によって異なるコードを実行すると効果的な場合があります。エラーが発生したときに追加でコードを実行したい場合や、値が大きく、または小さくなりすぎたときにメッセージを表示したい場合のことです。これを実現するには、コードの一部を条件文にします。
Swift には、コードに条件分岐を追加する手段が、if
文と switch
文の 2 通りあります。一般的に、シンプルな条件には if
文を用います。switch
文は、組み合わせが多岐にわたる複雑な条件に適していて、パターンマッチによって適切なコード分岐を選択しやすくなるような状況で役に立ちます。
if
シンプルな形式で、if
文は if
条件を 1 つ持ちます。条件が true
の場合にのみ、コードブロックを実行します。
var temperatureInFahrenheit = 30
if temperatureInFahrenheit <= 32 {
print("It's very cold. Consider wearing a scarf.")
}
// "It's very cold. Consider wearing a scarf." と出力
この例では、気温が華氏 32 度(水の氷点)以下であるかをチェックしています。もしそうであれば、メッセージが出力されます。そうでなければ、メッセージは出力されず、if
文の閉じ括弧の後に続くコードが実行されます。
if
文は、if
条件が false
になるときのために、else 節で別のコードブロックを持つことができます。このコードブロックを else
キーワードで示します。
temperatureInFahrenheit = 40
if temperatureInFahrenheit <= 32 {
print("It's very cold. Consider wearing a scarf.")
} else {
print("It's not that cold. Wear a t-shirt.")
}
// "It's not that cold. Wear a t-shirt." と出力
2 つの分岐のうちの 1 つが必ず実行されます。気温が華氏 40 度まで高くなっているため、スカーフを巻くようアドバイスするほど寒くはなく、else
側の分岐が代わりに実行されます。
複数の if
文をつなげることができます。
temperatureInFahrenheit = 90
if temperatureInFahrenheit <= 32 {
print("It's very cold. Consider wearing a scarf.")
} else if temperatureInFahrenheit >= 86 {
print("It's really warm. Don't forget to wear sunscreen.")
} else {
print("It's not that cold. Wear a t-shirt.")
}
// "It's really warm. Don't forget to wear sunscreen." と出力
ここでは、とりわけ暖かい気温のときに対する if
文が追加されています。最後の else
節はそのままで、暖かすぎず、寒すぎない気温のときに出力されます。
最後の else
節が必要ない場合には、除外することができます。
temperatureInFahrenheit = 72
if temperatureInFahrenheit <= 32 {
print("It's very cold. Consider wearing a scarf.")
} else if temperatureInFahrenheit >= 86 {
print("It's really warm. Don't forget to wear sunscreen.")
}
この例では、if
または else if
条件を満たすほど気温が寒くも暑くもなく、メッセージは出力されません。
Switch
switch
文は、いくつかのパターンに対して、値が一致するか比較します。そして、一致する最初のパターンに基づく適切なコードブロックを実行します。switch
文は、複数の状態に対応する if
文の代わりに使用できます。
最もシンプルな形式では、switch
文は 1 つ以上の同じ型の値と比較します。
switch some value to consider {
case value 1:
respond to value 1
case value 2,
value 3:
respond to value 2 or 3
default:
otherwise, do something else
}
switch
文は複数のケースで構成され、各ケースは case
キーワードで始まります。指定した値との比較に加え、Swift にはケースに対してより複雑なパターンを指定する方法がいくつかあります。これらの方法については、このセクションの後半で説明しています。
各 switch
ケースの本体は、if
文の分岐と似たような、分岐された別々の実行コードです。switch
文は、どの分岐を選択すべきかを特定します。
すべての switch
文は、網羅的である必要があります。つまり、すべての値が switch
ケースの 1 つに一致している必要があります。すべての値に対応する switch
ケースを定義することが適切でない場合、あらゆる値をカバーしてすべてのケースに対応するデフォルトを定義することができます。このケースを default
キーワードで示し、最後に定義する必要があります。
次の例は、小文字 1 字の someCharacter
に対する switch
文です。
let someCharacter: Character = "e"
switch someCharacter {
case "a", "e", "i", "o", "u":
print("\(someCharacter) is a vowel")
case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
"n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
print("\(someCharacter) is a consonant")
default:
print("\(someCharacter) is not a vowel or a consonant")
}
// "e is a vowel" と出力
switch
文の最初のケースは、英語にある 5 つの母音の小文字すべてに一致します。同じように、2 つ目のケースは英語にある子音の小文字すべてに一致します。
switch
ケースの一部として他の文字をすべて記述することは現実的ではないため、この switch
文は母音でも子音でもない他のすべての文字に一致する default
ケースとしています。これにより、switch
文を網羅的にすることができています。
暗黙的にフォールスルーしない
C や Objective-C の switch
文とは対照的に、Swift の switch
文はデフォルトでは各ケースの最後で次のケースにフォールスルーしません。そうならずに、はじめに一致した switch
ケースを完了後すぐ、明示的な break
文を必要とせずに、switch
文全体の実行を終了します。これにより、C と比較して switch
文はより安全でわかりやすくなっていて、誤って複数の switch
ケースを実行することを防ぐことができます。
break
は必要ではないものの、ケースの実行が完了する前にケースから抜け出すために break
文を使用することができます。詳細については、Break in a Switch Statement を確認してください。
各ケースの本体には、少なくとも 1 つ実行文が必要です。次のコードは、最初のケースが空になっているため有効ではありません。
let anotherCharacter: Character = "a"
switch anotherCharacter {
case "a":
case "A":
print("The letter A")
default:
print("Not the letter A")
}
// コンパイル時エラー
C での switch
文と異なり、この switch
文は "a"
と "A"
の両方に一致するわけではありません。むしろ、case "a":
に実行文が無いとコンパイル時エラーを報告します。このアプローチにより、次のケースへの意図しないフォールスルーを防ぎ、意図が明確で安全なコードになります。
1 つの switch
ケースにカンマ区切りで複数の一致対象を記述することができ、リストが長くなる場合には複数行に記述することができます。
switch some value to consider {
case value 1,
value 2:
statements
}
範囲一致
switch
ケースの値が、ある範囲に含まれているかを確認することができます。次の例は、サイズを表現する自然言語に対応する数値範囲を使用しています。
let approximateCount = 62
let countedThings = "moons orbiting Saturn"
var naturalCount: String
switch approximateCount {
case 0:
naturalCount = "no"
case 1..<5:
naturalCount = "a few"
case 5..<12:
naturalCount = "several"
case 12..<100:
naturalCount = "dozens of"
case 100..<1000:
naturalCount = "hundreds of"
default:
naturalCount = "many"
}
print("There are \(naturalCount) \(countedThings).")
// "There are dozens of moons orbiting Saturn." と出力
この例では、approximateCount
は switch
文で評価されます。各 case
は数値または数値の範囲と比較します。approximateCount
は 12 と 100 の間にあるため、naturalCount
には "dozens of"
が代入され、実行は switch
文の外に移ります。
...
) と半開範囲演算子 (..<
) 関数は、IntervalType
または Range
を返すようにオーバーロードされています。範囲は、switch
文の case
のように、特定の要素が含まれているかどうかを判断するときに使用することができます。範囲は連続した値のコレクションで、for
–in
文で繰り返し処理することができます。
タプル
タプルを使用して、同じ switch
文で複数の値をテストすることができます。タプルの各要素は、異なる値や値の範囲に対してテストすることができます。あるいは、ワイルドカードパターンであるアンダースコア記号 (_
) を使用して、あらゆる値を一致させることができます。
次の例は (Int, Int)
型のシンプルなタプルで点 (x, y) を表現し、グラフに分類します。
let somePoint = (1, 1)
switch somePoint {
case (0, 0):
print("(0, 0) is at the origin")
case (_, 0):
print("(\(somePoint.0), 0) is on the x-axis")
case (0, _):
print("(0, \(somePoint.1)) is on the y-axis")
case (-2...2, -2...2):
print("(\(somePoint.0), \(somePoint.1)) is inside the box")
default:
print("(\(somePoint.0), \(somePoint.1)) is outside of the box")
}
// "(1, 1) is inside the box" と出力
switch
文は、点が原点 (0, 0) にあるか、赤色の x 軸上か、オレンジ色の y 軸上か、青色の 4×4 の原点を中心とするボックス内か、ボックス外かを判定します。
C と異なり、Swift では同じ値に一致する switch
ケースを複数持つことができます。実際、点 (0, 0) はこの例にある 4 つのケースに一致します。複数ある場合には、最初に一致したケースが常に使われます。点 (0, 0) は最初に case (0, 0)
と一致するため、他のケースは無視されます。
値のバインディング
switch
ケースは、ケースの本体で使用するために、一時的な定数に値をバインドすることができます。ケースの本体内で一時的な定数に値をバインドするため、値のバインディング(バリューバインディング)と呼ばれています。
次の例は (Int, Int)
型のタプルで点 (x, y) を表現し、グラフに分類します。
let anotherPoint = (2, 0)
switch anotherPoint {
case (let x, 0):
print("on the x-axis with an x value of \(x)")
case (0, let y):
print("on the y-axis with a y value of \(y)")
case let (x, y):
print("somewhere else at (\(x), \(y))")
}
// "on the x-axis with an x value of 2" と出力
switch
文は、点が赤色の x 軸上か、オレンジ色の y 軸上か、軸上でない他の位置にあるかを判定します。
3 つの switch
ケースは、anotherPoint
からタプル値の一方または両方を取得してプレースホルダ定数 x
と y
を宣言します。最初のケース case (let x, 0)
は、y
の値が 0
の点に一致し、一時定数 x に点の x
値を代入します。同じように、次のケース case (0, let y)
は、x
の値が 0
の点に一致し、一時定数 y
に点の y
値を代入します。
宣言した一時定数は、ケースのコードブロック内で使用することができます。この例では、print(_:separator:terminator:)
関数で値を出力しています。
この switch
文には default
ケースが無いことに注目してください。最後のケース case let (x, y)
は、どんな値にでも一致するプレースホルダ定数のタプルで宣言しています。結果的に、残りの値すべてに一致するため、switch
文を網羅的にするための default
ケースは必要ありません。
where
switch
ケースは、追加の条件を判定する where
節を使用することができます。
次の例は点 (x, y) をグラフに分類します。
let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
case let (x, y) where x == y:
print("(\(x), \(y)) is on the line x == y")
case let (x, y) where x == -y:
print("(\(x), \(y)) is on the line x == -y")
case let (x, y):
print("(\(x), \(y)) is just some arbitrary point")
}
// "(1, -1) is on the line x == -y" と出力
switch
文は、点が x == y
になる緑色の斜線上か、x == -y
になる紫色の斜線上か、他の位置にあるかを判定します。
3 つの switch
ケースは、yetAnotherPoint
のタプル値を取得してプレースホルダ定数 x
と y
を宣言します。これらの定数は、動的なフィルターを生成する where
節に使用されています。switch
ケースは、where
節の条件が true
と評価される場合にのみ、point
の現在の値に一致します。
この例では、最後のケースが残りの値すべてに一致するため、switch
文を網羅的にするための default
ケースは必要ありません。
Portions of this page are translations based on work created and shared by Apple and used according to terms described in the Creative Commons Attribution 4.0 International License.