Rustにおける多重ネストでのbreakの挙動を確認する

私のRustの勉強の1つとして、Rustにおける多重ネスト(例えばfor文の入れ子)でbreakの挙動を確認してみます。

まずは

fn main() {
    for i in 0..3 {
        for j in 0..3 {
            for k in 0..3 {
                println!("i: {}, j: {}, k:{}", i, j, k);
            }
        }
    }
}

これの実行結果は当然ながら

i: 0, j: 0, k:0
i: 0, j: 0, k:1
i: 0, j: 0, k:2
i: 0, j: 1, k:0
i: 0, j: 1, k:1
...(中略)...
i: 2, j: 1, k:2
i: 2, j: 2, k:0
i: 2, j: 2, k:1

となります。

さて、お次は下のように最後のforループの中にbreakを入れてみます。

fn main() {
    for i in 0..3 {
        for j in 0..3 {
            for k in 0..3 {
                println!("i: {}, j: {}, k:{}", i, j, k);
                break;
            }
        }
    }
}

すると実行結果は下記のように、k=0の時の処理が行われた後、break文によって”最後のforループを"抜けています。

i: 0, j: 0, k:0
i: 0, j: 1, k:0
i: 0, j: 2, k:0
i: 1, j: 0, k:0
i: 1, j: 1, k:0
i: 1, j: 2, k:0
i: 2, j: 0, k:0
i: 2, j: 1, k:0
i: 2, j: 2, k:0

breakを別の所、例えば2番目のループに入れると、今度は"j=0の時の処理が行われた後、break文によって二番目のforループ"を抜けます。

fn main() {
    for i in 0..3 {
        for j in 0..3 {
            for k in 0..3 {
                println!("i: {}, j: {}, k:{}", i, j, k);
            }
            break;
        }
    }
}
i: 0, j: 0, k:0
i: 0, j: 0, k:1
i: 0, j: 0, k:2
i: 1, j: 0, k:0
i: 1, j: 0, k:1
i: 1, j: 0, k:2
i: 2, j: 0, k:0
i: 2, j: 0, k:1
i: 2, j: 0, k:2

なのでbreak文を使うと、"そのbreakが記述されているネストのみ抜ける"挙動になっているようです。

では、もっとネストの外に抜けたい時はどうするのかというと、以下のようにラベルを付け、break時に抜けたい所のラベルを指定します。

fn main() {
    'loop_i: for i in 0..3 {
        'loop_j: for j in 0..3 {
            'loop_k: for k in 0..3 {
                println!("i: {}, j: {}, k:{}", i, j, k);
                break 'loop_j;
            }
        }
    }
}

上の実行結果は下記のようになります

i: 0, j: 0, k:0
i: 1, j: 0, k:0
i: 2, j: 0, k:0

break 'loop_jとすることで、loop_jとラベルを付けた部分(二番目のループ)を抜けています。

breakで指定するラベルをloop_iにするとどうなるでしょうか。

fn main() {
    'loop_i: for i in 0..3 {
        'loop_j: for j in 0..3 {
            'loop_k: for k in 0..3 {
                println!("i: {}, j: {}, k:{}", i, j, k);
                break 'loop_i;
            }
        }
    }
}
i: 0, j: 0, k:0

最初の状態で出力をした後、breakでloop_iを抜ける=多重ループから抜けるようになりました。



今回は、Rustにおける多重ネスト(例えばfor文の入れ子)でbreakの挙動を確認してみました。

他に上記の説明をしているサイトを書きますので併せて見てみてください。

ネストとラベル - Rust By Example 日本語版

zenn.dev