制御フロー文は、プログラムの実行の流れを制御するために使用されます。これらは、コードブロックを実行するかどうかの決定、コードブロックの繰り返し、コードブロックの早期終了に使用されます。Moveには以下の制御フロー文があります(詳細は後述):

条件文

if 式はプログラム内で決定を行うために使用されます。条件式を評価し、式が真の場合にコードブロックを実行します。else と組み合わせることで、式が偽の場合に別のコードブロックを実行することができます。

if 式の構文は以下の通りです:

if (<条件式>) <式>;
if (<条件式>) <式> else <式>;

他の式と同様に、if の後に他の式が続く場合はセミコロンが必要です。else キーワードはオプションですが、結果の値が変数に代入される場合は必須です。これについては後で説明します。

    #[test]
    fun test_if() {
        let x = 5;

        // `x > 0` は条件式です。
        if (x > 0) {
            std::debug::print(&b"X is bigger than 0".to_string())
        };
    }

ifelse を使用して変数に値を代入する方法を見てみましょう:

    #[test]
    fun test_if_else() {
        let x = 5;
        let y = if (x > 0) {
            1
        } else {
            0
        };

        assert!(y == 1, 0);
    }

ここでは if 式の値を変数 y に代入しています。x が0より大きい場合、y には1が代入され、そうでない場合は0が代入されます。else ブロックは必須です。なぜなら、両方の分岐が同じ型の値を返す必要があるからです。else ブロックを省略すると、コンパイラはエラーを投げます。

条件式は、Moveにおける最も重要な制御フロー文の1つです。ユーザーが提供した入力や既に保存されているデータを使用して決定を行うことができます。特に、assert! マクロで条件が真かどうかをチェックし、真でない場合に実行を中止するのに使用されます。これについてはすぐに説明します!

ループによる文の繰り返し

ループはコードブロックを複数回実行するために使用されます。Moveには2つの組み込みループタイプがあります:loopwhile です。多くの場合、これらは互換的に使用できますが、通常 while は反復回数が事前にわかっている場合に使用され、loop は反復回数が事前にわかっていない場合や複数の終了ポイントがある場合に使用されます。

ループは、ベクターなどのコレクションを扱う場合や、特定の条件が満たされるまでコードブロックを繰り返したい場合に役立ちます。ただし、ループには注意が必要です。無限ループになる可能性があり、ガス枯渇やトランザクションの中止につながる可能性があるからです。

while ループ

while 文は、条件式が真である限りコードブロックを実行するために使用されます。if で見たように、条件式はループの各反復の前に評価されます。条件文と同様に、while ループも式であり、後に他の式が続く場合はセミコロンが必要です。

while ループの構文は以下の通りです:

while (<条件式>) { <式>; };

非常に単純な条件を持つ while ループの例を示します:

    // この関数は `x` 変数が10に達するまで反復し、
    // 戻り値は10に達するまでに要した反復回数です。
    //
    // `x` が0の場合、関数は10を返します。
    // `x` が5の場合、関数は5を返します。
    fun while_loop(mut x: u8): u8 {
        let mut y = 0;

        // これは `x` が10になるまでループします。
        // `x` が10以上の場合は一度も実行されません。
        while (x < 10) {
            y = y + 1;
            x = x + 1;
        };

        y
    }

    #[test]
    fun test_while() {
        assert!(while_loop(0) == 10, 0); // 10回
        assert!(while_loop(5) == 5, 0);  // 5回
        assert!(while_loop(10) == 0, 0); // ループは一度も実行されない
    }