web-dev-qa-db-ja.com

Swift 2-ifステートメントでbreakを使用するためのユースケース?

Swift 2のガイドには、ifステートメントのプログラム実行を終了できると記載されています。私は個人的にif文でのブレークを使用したことがありません。

Breakステートメントは、ループ、ifステートメント、またはswitchステートメントのプログラム実行を終了します... breakステートメントの後にステートメントラベルの名前が続くと、指定されたループ、ifステートメント、またはswitchステートメントのプログラム実行が終了しますそのラベルで。

Ifステートメントでbreakを使用するのはどのような状況ですか?この言語機能は役に立たないようです。

TEST:
if (true) {
    break TEST
}
17
Boon

Ifステートメントでbreakを使用するのは少し不自然に思えますが、スタイルが要求する場所は考えられません。ただし、if-else句のifステートメントの後半部分をスキップするときに、余分なレベルのインデントを節約できます。これは、深くネストされたループに役立ちます。

他の言語では、深くネストされた関数でエラーを処理するためにラベルを使用するのが人気のある(および/または論争の的になっている)イディオムです。たとえば、次のようにエラー時にループから抜け出すことができます。

func testBreak3() {
    // doesn't compile!!!
    let a = false, b = true, x = 10, y = 20, err = true
    if !a {
        if b && x > 0 {
            if y < 100 {
                if err {
                    break handleError
                }
                // some statements
            } else {
                // other stuff
            }

        }
    }
    return  // avoid error handling

    handleError:
    print("error")
    // handle the error
}

しかし、Swift(2.0を参照として使用している)では、ラベルは他の言語とは異なります。上記の例は2つの理由でコンパイルされません:ラベルがまだ宣言されていない場合使用されており、ラベルはdowhileif、またはcaseステートメントに直接関連付けられている必要があります。さらに、ifまたはdoステートメントでは、そのステートメントにラベルを付ける必要があります。次のように修正できますが、errorFlagged変数を介した追加の追跡により、ソリューションの魅力が低下し、リファクタリングが多くなります魅力的:

func testBreak() {
    let a = false, b = true, x = 10, y = 20, err = true
    var errorFlagged = false
    nestedIf: if !a {
        if b && x > 0 {
            if y < 100 {
                if err {
                    errorFlagged = true
                    break nestedIf
                }
                // some statements
            } else {
                // other stuff
            }
        }
    }

    // skip handling if no error flagged.
    if errorFlagged {
        print("error")
        // handle error
    }
}
11
rholmes

たとえば、数値のセット(偶数/有理/負の数値)を参照して数値(文字列を含む)を記述したい場合、コードは次のようになります。

if condition1 {
    // code
    if condition2 {
        // code
        if condition3 {
            // code
            if condition4 {
                //code
            }
        }
    }
}

guardを使用して)リファクタリングすることで、ネストされたifsなしで同じロジックを実現できます。

OuterIf: if condition1 {
    // code

    guard condition2 else { break OuterIf }
    // code

    guard condition3 else { break OuterIf }
    // code

    guard condition4 else { break OuterIf }
    // code
}

// reads even better when breaking out of "do"
scope: do {
    guard condition1 else { break scope }
    // code

    guard condition2 else { break scope }
    // code

    guard condition3 else { break scope }
    // code

    guard condition4 else { break scope }
    // code

}

これはswitchfallthroughでも実現できると思うかもしれませんが、これは「通常の」ケースでは機能しません。 tも評価されました。

したがって、fallthoughは条件付きで呼び出す必要があります。

これは機能しますが、その「美しさ」は言うまでもありませんが、あまり読みにくいです。

let x = 4
switch x {
case _ where condition1:
    // code
    if condition2 { fallthrough }
case _ where false:
    // code
    if condition3 { fallthrough }
case _ where false:
    // code
    if condition4 { fallthrough }
case _ where false:
    // code
    break
default: break
}
15
Qbyte

これは古いトピックであることはわかっていますが、今はブレークを使用していて、それが必要でした。だから私の例では、オブジェクトの配列があります。ユーザーがセルをタップすると、そのセル内のオブジェクトに対してi.parameterがTrueになります。配列内のすべてのオブジェクトがi.parameter = Trueを持っていることを知る必要があります。これがゲームを停止するための条件です。

func forTimer(){
   for i in array {
   if i.parameter = false
   break
 }
}
timer = Timer.scheduledTimer(timeInterval: 0.001, target: self, selector: #selector(forTimer), userInfo: nil, repeats: true)

1つのi.parameter = falseの場合でも、配列の残りを確認する必要はありません。この関数はミリ秒ごとに呼び出されるため、アレイ全体をミリ秒ごとにチェックする必要はありません。

0
Anna Orlova