Defer Statement

May 21, 2026 ยท View on GitHub

defer schedules a block to run when the current scope exits, regardless of how it exits.

func processFile() {
    var file = openFile("data.txt")
    defer { file.close() }
    processContents(file)
}

Execution order

Deferred blocks run in LIFO order (last defer executes first):

func test() {
    defer { trace("1") }  // executes third
    defer { trace("2") }  // executes second
    defer { trace("3") }  // executes first
}
// Output: 3, 2, 1

Scoped defer runs when its enclosing block exits:

func test() {
    defer { trace("outer") }
    {
        defer { trace("inner") }
        trace("block")
    }  // "inner" runs here
    trace("function")
}  // "outer" runs here
// Output: block, inner, function, outer

Variable access

Deferred blocks capture variables by reference โ€” they see the value at the time they execute:

func test() {
    float value = 1
    defer {
        if(value == 2)
            processValue(value)
    }
    value = 2
}  // processValue(2) is called

Restrictions

  • return is not allowed inside defer blocks (it is allowed inside lambdas within them)
  • break and continue only affect loops that are inside the defer block itself