Control Flow

7.1 if / else

No parentheses around conditions. Braces are required.

if x > 0 {
	println('positive')
} else if x < 0 {
	println('negative')
} else {
	println('zero')
}

grade := if score >= 90 { 'A' } else if score >= 80 { 'B' } else { 'C' }   // if as an expression

// if with an option/result guard (unwrap)
if val := m['key'] {
	println('found ${val}')
}

7.2 match

match must be exhaustive: cover all enum or sum-type variants, or include else.

match os_name {
	'linux' { println('Linux') }
	'macos', 'darwin' { println('Mac') }
	else { println('Other') }
}

kind := match n {
	0 { 'zero' }
	1...9 { 'single digit' }      // inclusive range (three dots in match)
	else { 'large' }
}

// match on enums (exhaustive: no else needed if all variants are covered)
match color {
	.red { println('stop') }
	.yellow { println('slow') }
	.green { println('go') }
}

// match without a value: like if-else chains
match true {
	x < 0 { println('neg') }
	x == 0 { println('zero') }
	else { println('pos') }
}

7.3 for (the Only Loop Keyword)

// 1. Array / map iteration
names := ['Ana', 'Bo']
for name in names { println(name) }
for i, name in names { println('${i}: ${name}') }

m := {'one': 1, 'two': 2}
for key, value in m { println('${key}=${value}') }

// 2. Range (exclusive end)
for i in 0 .. 5 { println(i) }          // 0..4

// 3. Condition (while-style)
mut n := 0
for n < 5 { n++ }

// 4. C-style
for i := 0; i < 10; i += 2 { println(i) }

// 5. Infinite
for {
	if done() { break }
}

// Mutating elements
mut nums := [1, 2, 3]
for mut x in nums { x *= 2 }

// Labeled break / continue
outer: for i in 0 .. 5 {
	for j in 0 .. 5 {
		if i * j == 6 { break outer }
		if j > i { continue outer }
	}
}

7.4 defer

defer blocks run in reverse order at function exit (not block exit). defer(fn) {} is function-scoped explicitly in newer versions.

fn read_file() ! {
	mut f := os.open('data.txt')!
	defer { f.close() }        // runs when the function returns
	// ... use f
}

7.5 goto (Unsafe Only)

unsafe {
	goto skip
}
println('skipped')
skip:
println('after label')