StarknetAstro

StarknetAstro

09_Cairo Flow Control

Control Flow in Cairo#

This article uses Cairo compiler version 2.0.0-rc0. Since Cairo is being updated rapidly, the syntax may vary slightly in different versions. The content of this article 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 simple to use and does not require parentheses to enclose the condition.

Let's take a look at the case with 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, the subsequent conditions will not be evaluated. In the example above, even if the third condition number - 2 == 1 is true, it will not be executed because the second condition number == 3 is already satisfied.

Special if statement with the same effect as the ternary operator#

This statement combines the let statement and 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 managed using continue and break. Let's take a 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, the loop continues to the next iteration using the continue statement. The logic after continue will not be executed. When i is equal to 10, the loop is exited using the break statement.

  • A return value needs to be added after break. If there is no return value, the unit type () is used, but 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

Getting the return value of a 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();
}

In the above code, the final value of t is 10.

Commonality between if and loop: Getting 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 enclosed in 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 general way to obtain the result of an expression is to directly get the return value of the code block within {}.

use debug::PrintTrait;

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

    y.print();
}

We can understand the combined syntax of if, loop, and let as a sugar syntax based on the general 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.