web-dev-qa-db-ja.com

SwiftのSwitchステートメント

私はSwiftの構文を学んでいますが、なぜ次のコードが期待どおりに機能しないのか疑問に思います:

for i in 1...100{

    switch (i){
    case 1:
        Int(i%3) == 0
        println("Fizz")
    case 2:
        Int(i%5) == 0
        println("Buzz")
    default:
        println("\(i)")
    }  
}

数字が3(3、6、9、12など)で割り切れるたびにFizzを印刷し、5で割り切れるたびにBuzzを印刷したいのですが、不足しているパズルは何ですか?

注:私は次を使用してそれを解決しました:

for ( var i = 0; i < 101; i++){

    if (Int(i%3) == 0){
        println("Fizz")
    }   else if (Int(i%5) == 0){
        println("Buzz")
    }   else {
        println("\(i)")
    }   
}

Switchを使用してこれを解決する方法を知りたいです。ありがとうございました。

35
Evgeniy Kleban

FizzBu​​zzゲーム の通常のルールは、3の倍数をすべて「Fizz」に、5の倍数を「Buzz」に、両方の3の倍数を置き換えることです and5 by "FizzBu​​zz"。

これは、タプル(i % 3, i % 5)のswitchステートメントで実行できます。 _は「任意の値」を意味することに注意してください。

for i in 1 ... 100 {
    switch (i % 3, i % 5) {
    case (0, 0):
        print("FizzBuzz")
    case (0, _):
        print("Fizz")
    case (_, 0):
        print("Buzz")
    default:
        print(i)
    }
}
101
Martin R

Swift=値バインディングをサポートするSwitchステートメントは.
これにより、特定の条件に一致する値(where句で評価)を一時変数(ここではxy)に割り当てることができます。

for i in 1...100 {
    switch (i){
    case let x where x%3 == 0:
        println("Fizz")
    case let y where y%5 == 0:
        println("Buzz")
    default:
        println("\(i)")
    }
}

ケース本体で割り当てられたtemp値を使用することもできます。

更新:
Matt Gibsonはコメントで指摘しています。ケース本体で使用しない場合は、一時変数への割り当てを省略できます。
したがって、上記のコードのより簡潔なバージョンは次のようになります。

for i in 1...100 {
    switch (i){
    case _ where i%3 == 0:
        println("Fizz")
    case _ where i%5 == 0:
        println("Buzz")
    default:
        println("\(i)")
    }
}

補足:2つのコードサンプルはわずかに異なります(最初のコードサンプルは範囲0〜100を入力として使用し、2番目のコードサンプルは1〜100で動作します)。私のサンプルは、最初のコードスニペットに基づいています。

20

これは、Swiftでswitchステートメントを使用する方法を知りたいだけで、ここに来る人にとってより一般的な答えです。

一般的な使用法

switch someValue {
case valueOne:
    // executable code
case valueTwo:
    // executable code
default:
    // executable code
}

let someValue = "horse"

switch someValue {
case "horse":
    print("eats grass")
case "wolf":
    print("eats meat")
default:
    print("no match")
}

注:

  • breakステートメントは必要ありません。これがデフォルトの動作です。 Swift switchケースは「フォールスルー」しません。次のケースでコードにフォールスルーする場合は、fallthroughを明示的に使用する必要がありますキーワード。
  • すべてのケースに実行可能コードを含める必要があります。ケースを無視したい場合は、単一のbreakステートメントを追加できます。
  • ケースは網羅的でなければなりません。つまり、すべての可能な値をカバーする必要があります。十分なcaseステートメントを含めることができない場合は、defaultステートメントを最後に含めて、他の値をキャッチできます。

Swift switchステートメントは非常に柔軟性があります。以下のセクションでは、他の使用方法について説明します。

複数の値の一致

値をコンマで区切って使用すると、1つのケースで複数の値を一致させることができます。これは、複合ケースと呼ばれます。

let someValue = "e"

switch someValue {
case "a", "b", "c":
    // executable code
case "d", "e":
    // executable code
default:
    // executable code
}

全体intervalsに一致させることもできます。

let someValue = 4

switch someValue {
case 0..<10:
    // executable code
case 10...100:
    // executable code
default:
    // executable code
}

tuplesを使用することもできます。この例は、 documentation から変更されています。

let aPoint = (1, 1)

switch aPoint {
case (0, 0):
    // only catches an exact match for first and second
case (_, 0):
    // any first, exact second
case (-2...2, -2...2):
    // range for first and second
default:
    // catches anything else
}

値のバインド

switch値から一時的な定数または変数を作成したい場合があります。 caseステートメントの直後にこれを行うことができます。値バインディングが使用される場所はどこでも、任意の値に一致します。これは、上記のTupleの例で_を使用することに似ています。次の2つの例は、 documentation から変更されています。

let anotherPoint = (2, 0)

switch anotherPoint {
case (let x, 0):
    // can use x here
case (0, let y):
    // can use y here
case let (x, y):
    // can use x or y here, matches anything so no "default" case is necessary
}

whereキーワードを使用して、一致をさらに絞り込むことができます。

let yetAnotherPoint = (1, -1)

switch yetAnotherPoint {
case let (x, y) where x == y:
    // executable code
case let (x, y) where x == -y:
    // executable code
case let (x, y):
    // executable code
}

さらなる研究

  • この答えは、クイックリファレンスになることを目的としています。詳細については documentation をすべてお読みください。理解するのは難しくありません。
13
Suragch

これはそれができる方法です

var i = 0

switch i  {

case i where i % 5 == 0 && i % 3 == 0: print(" Fizz Buzz")
case i where i % 3 == 0 : print("Fizz")
case i where i % 5 == 0 : print("Buzz")
default: print(i)

}
2
user6257714

スイッチの業界標準の動作により、 "Go to Fail" に類似したバグが発生する可能性があります。

基本的に、コードは、コードを読むときにコードが行うように見えるとは限らないため、重大なバグをスキップするコード監査者になります。

これに対抗するため、Apple= switchステートメントは、Swift=業界標準と同じように動作しないはずです。特に:

  • すべてのケースの終わりに自動ブレークがあります。複数のcaseステートメントを実行することは不可能です。
  • Caseステートメントの1つが欠落することが理論的に可能である場合、コードはまったくコンパイルされません。 In Swiftどの値が提供されても、caseステートメントの1つは常に実行されます。enumを提供する場合、すべてのenum値を処理する必要があります。新しい値が既存のenumに追加される場合新しいcaseステートメントが追加されるまでコードはコンパイルされません32ビット整数を指定する場合、32ビット整数の可能な値をすべて処理する必要があります。
1
Abhi Beckert