defer
defer schedules a block to run when the current scope ends — no matter which
path it exits by. Multiple defers run in LIFO order (the last scheduled
runs first), which is perfect for undoing setup in reverse order:
Cleanup happens on scope exit, in reverse order of scheduling.
19-defer.zolo
// Feature: `defer` — cleanup on scope exit (LIFO)
// Syntax: `defer expr` or `defer { ... }`
// When to use: ensure resources are released
// (close file, drop lock, restore state) even if
// the function returns early or panics.
// Execution order: LIFO — the last `defer` declared
// runs first.
fn process_file() {
print("opening file")
defer print("closing file") // runs last
defer print("flushing") // runs second-to-last
print("processing")
print("done")
}
process_file()
// expected:
// opening file
// processing
// done
// flushing
// closing file
// Deferred cleanup combined with early return.
// SKIP: `defer` combined with an explicit `return <value>` from a
// typed function currently fails to lower (the runtime needs to wrap
// the body in `pcall` for defer-on-panic; this conflicts with early
// return). The pattern below uses a void function instead.
fn safe_op(ok: bool) {
print("start")
defer print("cleanup guaranteed")
if !ok {
print("error -- returning early")
return
}
print("success")
}
print("--- ok call ---")
safe_op(true)
print("--- failed call ---")
safe_op(false)
See also