Control Flow, Loops & Labeled Blocks
loop without break has type "never returns" and can be used where any type is expected.
12.1 if / else
if (balance >= amount) {
withdraw(amount);
} else {
abort EInsufficientFunds
};
let fee = if (vip) 0 else 100;12.2 while and loop
loop without break has type "never returns" and can be used where any type is expected. In Move 2024, break can carry a value out of loop: let x = loop { break 42 };.
let mut i = 0;
let mut sum = 0;
while (i < 10) {
sum = sum + i;
i = i + 1;
};
let mut n = 0;
loop {
n = n + 1;
if (n == 5) continue;
if (n > 10) break;
};12.3 for loops (Aptos Move 2)
Sui Move has no for statement; use while, or the integer and vector macros:
// Aptos Move 2
let sum = 0;
for (i in 0..10) {
sum += i; // compound assignment (Move 2.1+)
};// Sui Move 2024
let mut sum = 0;
10u64.do!(|i| sum = sum + i);
vector[1, 2, 3].do!(|x| sum = sum + x);12.4 Labeled loops and blocks
Both dialects support labels for breaking out of nested loops:
Sui Move 2024 also supports labeled blocks that return early with a value:
'outer: loop {
let mut j = 0;
loop {
j = j + 1;
if (j == 3) continue 'outer;
if (j == 100) break 'outer;
};
};// Sui Move 2024
fun classify(x: u64): u64 {
let category = 'calc: {
if (x == 0) return 'calc 0;
if (x < 10) return 'calc 1;
2
};
category * 100
}12.5 return and abort
abort code stops execution and reverts every effect of the transaction.
fun find(v: &vector<u64>, target: u64): Option<u64> {
let mut i = 0;
while (i < v.length()) {
if (v[i] == target) return option::some(i);
i = i + 1;
};
option::none()
}
fun must_be_positive(x: u64) {
if (x == 0) abort 42;
}🧪 Part I Exercises
Install either the Sui CLI or the Aptos CLI, start a localnet, fund an address from the faucet, and print your balance.
Create a new package, publish the counter module from Chapter 6 for your chain, call increment three times, and inspect the result in an explorer.
Write a function average(v: &vector<u64>): u64 that returns 0 for an empty vector and never overflows (hint: accumulate in u128).
Write is_prime(n: u64): bool using a while loop, and a labeled loop version that exits early.
Demonstrate each of these aborts in a test: overflow on u8 addition, division by zero, and a failed as u8 cast.
Write reverse_string(s: String): String for ASCII input using std::ascii and vectors.
Explain, in your own words, why a Coin type without copy or drop prevents both double-spending and accidental burning.
Convert a Solidity mapping(address => uint256) balance ledger into a Move design for both Sui (objects) and Aptos (resources). Write the struct definitions only.
Write fizzbuzz(n: u64): vector<String> returning "Fizz", "Buzz", "FizzBuzz", or the number as a string.
Configure Move.toml with a named address and a local dependency on a second package; call a function from the dependency.