StarknetAstro

StarknetAstro

09_Flow Control in Cairo

Control Flow in Cairo#

This article uses the Cairo compiler version: 2.0.0-rc0. Since Cairo is being rapidly updated, the syntax may vary slightly in different versions, and the article content will be updated to the stable version in the future.

if statement#

use debug::PrintTrait;

fn main() {
    let number = 3;

    if number == 3 {
        'condition was true'.print();
    } 
}

It is easy to use and does not require enclosing the condition in parentheses.

Let's take a look at the case of multiple conditions:

use debug::PrintTrait;

fn main() {
    let number = 3;

    if number == 12 {
        'number is 12'.print();
    } else if number == 3 {
        'number is 3'.print();
    } else if number - 2 == 1 {
        'number minus 2 is 1'.print();
    } else {
        'number not found'.print();
    }
}

The execution order of multiple conditions is from top to bottom. Once a condition is satisfied, it will exit and no longer evaluate the remaining conditions. In the example above, the second condition number == 3 is already satisfied, so even if the third condition is true, it will not be executed.

Special if statement, achieving the same effect as the ternary operator#

This statement combines the let statement and the if statement together.

use debug::PrintTrait;

fn main() {
    let condition = true;
    let number = if condition {5} else {6};

    if number == 5 {
        'condition was true'.print();
    }
}

In the above code, if condition is true, number will be assigned as 5; if condition is false, number will be assigned as 6.

The ternary operator in Solidity is as follows:

bool condition = true;
uint256 a = condition ? 5 : 6;

loop statement#

loop allows for an infinite loop, and control can be achieved using continue and break. Let's first look at an example:

use debug::PrintTrait;

fn main() {
    let mut i: usize = 0;
    loop {
        i += 1;

        if i < 10 {
            'again'.print();
            continue;
        }

        if i == 10 {
            break ();
        };
    }
}

In the above code, i is incremented, and when it is less than 10, it will continue to the next iteration using the continue instruction. The logic after continue will not be executed. When i is equal to 10, it will break out of the loop using the break instruction.

  • A return value needs to be added after break, and if there is no return value, the unit type () is used. It cannot be omitted.

Note: When executing Cairo code with loop, the --available-gas option needs to be used to specify the gas limit. For example:

cairo-run --available-gas 200000 $CairoFile

Obtaining the return value of loop#

As mentioned earlier, break must be followed by a return value, and we can obtain this return value:

use debug::PrintTrait;

fn main() {
    let mut i: usize = 0;
    let t = loop {
        i += 1;

        if i >= 10 {
            break i;
        };
    };

    t.print();
}

The final value of t in the above code is 10.

Commonality of if and loop: Obtaining the result of an expression#

Both if and loop can be combined with let to obtain the result of an expression, which is the return value of the code block inside the curly braces. For example:

let number = if condition {5} else {6};

and

let t = loop {
    i += 1;

    if i >= 10 {
        break i;
    };
};

In Cairo, the common way to obtain the result of an expression is to directly get the return value of the code block inside {}.

use debug::PrintTrait;

fn main() {
    let y = {
        let x = 3;
        x + 1
    };

    y.print();
}

The value of y in the above code is 4.

The combined syntax of if, loop, and let can be understood as syntactic sugar based on the common way of obtaining the result of an expression.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.