Open5

[Swift] switch

🍤🍤

Switch概要

  • switch文はある複数のマッチングパターンを比較するやつ。
  • マッチングに成功した最初のパターンに基づいて、適切なコードブロックが実行される。
  • それぞれのケースはcaseキーワードで記述される。
  • switchはどのケースを選択すべきなのか決定する。
一番単純なswitch文
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ケースのいずれかに一致しなければならない。
  • もしすべての値に対してケースを用意することが適切でない場合は、デフォルトのケースを定義する。
  • デフォルトケースはdefaultキーワードで示され、常に最後に表示されなければならない。
  • この例では、switch 文を使用して、someCharacter:someCharacter という小文字の一文字について検討している。
let someCharacter: Character = "z"
switch someCharacter {
case "a":
    print("The first letter of the alphabet")
case "z":
    print("The last letter of the alphabet")
default:
    print("Some other character")
//デフォルトケースを使ってaとz以外のすべての文字にマッチするようにしている。
}
// Prints "The last letter of the alphabet"
  • C や Objective-C の switch 文はとは対照的に、Swift の switch 文は、デフォルトで各ケースの底を通り抜けて次のcaseには行かない。明示的な break 文をかかなくても、最初に一致する switch ケースが完了した時点で処理を抜ける。
  • つまり、C や Objective-C におけるSwitch文と比較し、安全性が高くなっている。
  • もしも意図的に次のcase文も実行したい、という場合はfallthroughを使うと実現できる。
fallthrough
let num = 0
var str = ""
switch num {
case 0:
    str += "2"
    fallthrough
default:
    str += "です"
    print(str)
}
//2です
🍤🍤
  • 各case文においては、少なくとも1つは実行可能な文が含まれていないといけない。
  • また、大文字・小文字は明確に区別される。
switch
let anotherCharacter: Character = "a"
switch anotherCharacter {
case "a": // Invalid, the case has an empty body
case "A":
    print("The letter A")
default:
    print("Not the letter A")
}
// This will report a compile-time error.
//case "a": には実行可能な文が含まれていないというコンパイル時エラーが報告される。
  • この方法は、あるケースから別のケースへの偶発的な抜け落ちを回避し、より安全で意図が明確なコードを作成することに寄与する。
  • a "と "A "の両方にマッチする1つのケースでスイッチを作成することもできる。
  • 複数の値をswitchに持つケースのことを複合ケースという。複合ケースは2つの値をカンマで区切って作成する。
  • 読みやすくするために複数ケースを複数行にわたってまとめることもできる。
複数ケース
switch anotherCharacter {
case "a", "A","b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
     "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
    print("The letter A")
default:
    print("Not the letter A")
}
// Prints "The letter A"
  • インターバルマッチングという手法もある。以下のように、特定の範囲内に収まっているかどうかをチェックしている。
Interval Matching
let approximateCount = 62
let countedThings = "moons orbiting Saturn"
let 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).")
// Prints "There are dozens of moons orbiting Saturn."
🍤🍤
  • タプルを使用すると、同じswitch文の中で複数の値をテストすることができる。
  • タプルの各要素は、異なる値または値の間隔に対してテストすることができる。
  • また、ワイルドカードパターンとして知られるアンダースコア文字(_)を使用すると、あらゆる可能性のある値にマッチさせることができる。
  • 以下の例では、(Int, Int)型の単純なタプルとして表現された(x, y)点を取り上げ、例に続くグラフ上で分類している。
switch Tuples
let somePoint = (1, 1)
switch somePoint {
case (0, 0):
    print("\(somePoint) is at the origin")
case (_, 0):
    print("\(somePoint) is on the x-axis")
case (0, _):
    print("\(somePoint) is on the y-axis")
case (-2...2, -2...2):
    print("\(somePoint) is inside the box")
default:
    print("\(somePoint) is outside of the box")
}
// prints "(1, 1) is inside the box"

  • switch文は、点が原点(0, 0)にあるか、赤のX軸上にあるか、緑のY軸上にあるか、原点を中心とした青の4×4のボックスの中にあるか、ボックスの外にあるかを決定する。
  • C言語とは異なり、Swiftでは複数のスイッチケースで同じ値や値を考慮することができます。実際、点 (0, 0) はこの例では4つのケースすべてにマッチする可能性がある。
  • 複数のマッチが可能な場合、最初にマッチするケースが常に使用される。
  • 点 (0, 0) は、最初にケース (0, 0) にマッチするので、他のマッチするケースはすべて無視されることになる。
🍤🍤
  • 値をBindingする。
  • switchケースは、マッチした値を一時的な定数や変数に命名し、ケース本体で使用することができる。
  • 値がケース本体の一時的な定数や変数に束縛されることから、Value Bindings(値束縛)と呼ばれている
Value Bindings
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))")
}
// Prints "on the x-axis with an x value of 2"

  • switch文は、点が赤いX軸上にあるか、緑のY軸上にあるのか、それ以外(いずれの軸上にもない)かを決定する。
  • 3つのスイッチケースはプレースホルダー定数xとyを宣言し、一時的にotherPointのタプル値の一方または両方を取得する。
  • 2 番目のケース (0, let y) は、x 値が 0 の任意の点にマッチし、その点の y 値を一時的な定数 y に代入する。
  • 一時定数を宣言した後は、ケースのコードブロックの中で使用することができる。
  • この switch 文は、デフォルトの case を持たない。
  • 最後のケースである case let (x, y) は、2つのプレースホルダ定数のタプルを宣言しており、どのような値にもマッチすることができる。
  • anotherPointは常に2つの値のタプルであるため、このケースは残りのすべての値にマッチし、switch文を網羅的にするためのデフォルトケースは必要ではない。
🍤🍤
enumとresultの組み合わせ
enum ColorType {
    case Red
    case Green
    case Blue
}
var color = ColorType.Red

switch color {
case .Red:
    print ("赤色が選択されました")
case .Green:
    print("緑色が選択されました")
case .Blue:
    print("青色が選択されました")
}