Skip to content
Kavachकवच

Break/Continue

Also known as: break continue exit leave loop skip next iteration

● Beginner4 minBefore this: For Loop, While LoopSpec 4.6

break leaves a loop at once; continue skips the rest of this round and starts the next.

break

Stop looking once you have found what you need:

fn main() {
    for n in [4, 8, 15, 16, 23] {
        if n % 2 != 0 {
            print("first odd number: {n}")
            break
        }
    }
}

The program ran and printed:

kavach run break.kav

first odd number: 15
break.kav: Kavach code, then what running it prints

continue

Skip the items you don't want, and carry on with the rest:

fn main() {
    for n in 1..=6 {
        if n % 3 == 0 {
            continue
        }
        print(n)
    }
}

The program ran and printed:

kavach run continue.kav

1245
continue.kav: Kavach code, then what running it prints

break and continue act on the innermost loop they are in. Both work in for and while loops.

Leaving an outer loop: labels

To leave several loops at once, name the outer one: a label and : before for or while. Then break outer leaves it, from however deep inside:

fn main() {
    const grid = [[1, 2, 3], [4, 42, 6], [7, 8, 9]]
    const target = 42
    let found = "nowhere"
    outer: for r in 0..grid.len() {
        for c in 0..grid[r].len() {
            if grid[r][c] == target {
                found = "row {r}, column {c}"
                break outer
            }
        }
    }
    print("{target} is at {found}")
}

The program ran and printed:

kavach run labeled.kav

42 is at row 1, column 1
labeled.kav: Kavach code, then what running it prints

continue with a label goes on with that loop's next round, skipping the rest of the inner one:

fn main() {
    const orders = [[5, 10], [3, -1, 8], [7]]
    rows: for items in orders {
        let total = 0
        for qty in items {
            if qty < 0 {
                print("skipping an order with a bad item")
                continue rows
            }
            total += qty
        }
        print("order total {total}")
    }
}

The program ran and printed:

kavach run label-continue.kav

order total 15skipping an order with a bad itemorder total 7
label-continue.kav: Kavach code, then what running it prints

A plain break still leaves only the innermost loop. A label must name a loop around it, in the same function:

fn main() {
    outer: for i in 0..3 {
        for j in 0..3 {
            if j == 1 {
                break inner
            }
        }
    }
}

The compiler refused the program:

kavach run label-wrong.kav

error: `break inner` names no loop around it: the loops around it are named `outer`. A label goes before its loop, as `inner: for … {`, in the same function (spec 4.6)
label-wrong.kav: Kavach code, then what running it prints
fn main() {
    outer: for i in 0..3 {
        const _ = [1, 2].map(n => {
            if n == 2 {
                break outer
            }
            n
        })
    }
}

The compiler refused the program:

kavach run label-lambda.kav

error: `break outer` names no loop around it: it is inside a lambda or `spawn`, whose body is a function of its own, so it can't leave a loop outside it. A label goes before its loop, as `outer: for … {`, in the same function (spec 4.6)
label-lambda.kav: Kavach code, then what running it prints

Try it yourself

Add up the even numbers from 1 to 10, using continue to skip the odd ones.
Show the answer
fn main() {
    let total = 0
    for n in 1..=10 {
        if n % 2 != 0 {
            continue
        }
        total += n
    }
    print(total)
}

The program ran and printed:

kavach run sum-even.kav

30
sum-even.kav: Kavach code, then what running it prints
Go deeper the why, for readers who want it

Labels work as in JavaScript, Java and Rust. A lambda or a spawn body is a function of its own, so a break inside one can't leave a loop outside it. When nested loops grow long, moving them into a function and using return is often clearer still: the function's name says what the loops are for.