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.