Control Flow
Jiang separates control-flow statements from expressions that produce values. Blocks, if, and switch can produce values; return, throw, break, and continue do not continue normally.
Blocks
Section titled “Blocks”Int value = { Int base = 40; base + 2}A block’s value comes from its final tail expression. Without a tail expression, the block value is ().
An if condition is followed directly by a block. As a statement, else may be omitted:
if value < 0 { print("negative");}As an expression, if must include else and both branches must produce compatible values:
Int sign = if value < 0 { -1} else { 1}Statement-style branches can still include else:
if value < 0 { print("negative");} else { print("non-negative");}switch
Section titled “switch”switch matches patterns and can produce a value:
enum Mode { read, write,}
Mode mode = Mode.read;
Int code = switch mode { .read => 1, .write => 2,}Branches may use a block:
Int code = switch mode { .read => { print("read"); 1 }, .write => 2,}Int! count = 0;while count < 5 { count = count + 1;}break exits the current loop and continue starts the next iteration:
while count < 10 { count = count + 1;
if count == 3 { continue; } else { print(count); }
if count == 8 { break; }}for in
Section titled “for in”for pattern in expr iterates arrays, slices, and other iterable values:
Int[_] values = [10, 20, 30];
for item in values { print(item);}Tuple destructuring is a separate statement inside the loop:
(Int, Int)[_] pairs = [(1, 2), (3, 4)];
for pair in pairs { (_ left, _ right) = pair; print(left + right);}Ranges use start..end:
for i in 0..10 { print(i);}guard is used for early exit while carrying successful bindings into the following scope:
() print_value(Int? maybe) { guard maybe is some value else { return (); }
print(value); return ();}The else block must be non-empty and end in return, break, continue, or throw.
defer runs when the current block exits:
defer handle$.free();
defer { log("closing"); handle$.free();}Use defer expr; for a single operation or defer { ... } for several operations.
try catch
Section titled “try catch”try expr catch (...) => fallback handles a T@E result:
Int value = try parse(text) catch (err) => { log_error(err); 0}Use catch () when the error value is not needed:
Int value = try parse(text) catch () => 0;