Menu

Golang While Loop: How to Write while and do-while in Go

Go has no while keyword. A for loop with only a condition is Go's while loop, for with no condition is an infinite loop, and a do-while is an infinite loop with the check at the end.

This page includes runnable editors - edit, run, and see output instantly.

Go has no while keyword. Write for followed by a condition, and you have a while loop:

The condition is checked before every iteration, so if it is false at the start the body never runs. This is identical to while (balance < 2000) in C, Java or JavaScript, minus the parentheses and the keyword. Go's designers chose one loop keyword for every loop shape; see the for loop page for all four forms.

while(true): the Infinite Loop

Leave out the condition entirely and the loop runs until something inside ends it:

for { } is the idiomatic spelling. for true { } compiles too, but reads as if the author came from another language.

Four things end an infinite loop: break (leaves the loop), return (leaves the function), a panic, and os.Exit. A program whose main sits in for {} with none of these runs until it is killed, which is exactly right for a server or worker.

do-while

A do-while runs the body once before checking the condition. Go has no dedicated syntax. Put the check at the end of an infinite loop:

The body runs at least once no matter what, which is the defining property of do-while. The random source uses a fixed seed so the output is the same on every run; use rand.IntN without a seeded source for real randomness.

A second form keeps the condition in the header by forcing the first pass:

for first := true; first || condition(); first = false {
	// body
}

It works, but the infinite loop with a break at the end is easier to read, and it is what most Go code does.

Reading Until Done

The most common while loop in real Go code reads input until it runs out. bufio.Scanner is designed for it: Scan returns false at the end of input or on an error, so it is the loop condition:

Swap strings.NewReader(input) for os.Stdin and the same loop reads the user's input line by line. Check scanner.Err() after the loop: Scan returning false does not tell you whether input ended normally or failed.

break and continue

Both work in every form of for:

In a condition-only loop, continue jumps straight to the condition. That makes a subtle bug easy: if the counter is updated at the bottom of the body, a continue above it skips the update and the loop never ends. Update the counter at the top, as above, or use a three-clause for whose post statement runs even after continue.

Waiting for Something

A loop that waits for a condition should block or sleep, not spin:

// Wrong: burns a CPU core while waiting
for !ready {
}

// Better: poll with a delay
for !isReady() {
	time.Sleep(100 * time.Millisecond)
}

Polling a plain variable that another goroutine writes is also a data race. Between goroutines, wait on a channel, a sync.WaitGroup or a sync.Cond instead, or use select with a timer. For retry loops with a limit, prefer a counted for so the loop cannot run forever:

for attempt := 1; attempt <= 5; attempt++ {
	if err := connect(); err == nil {
		break
	}
	time.Sleep(time.Duration(attempt) * 200 * time.Millisecond)
}

Common Mistakes

  • Forgetting to change the condition variable. for i < 10 { fmt.Println(i) } never ends. Every while loop needs something in the body that moves it toward the exit.
  • Writing while. while x < 5 {} gives syntax error: unexpected name x at end of statement, because while is not a keyword; the compiler reads it as an ordinary name.
  • Parentheses from habit. for (x < 5) {} compiles, and gofmt removes the parentheses.
  • Declaring the variable in the loop. for n := 10; n > 0 {} is a syntax error; a loop with an init clause needs all three clauses. Declare n before the loop, or write the full three-clause form.

Frequently Asked Questions

Does Go have a while loop?

Not as a keyword. Go uses for for every loop, and a for with only a condition is exactly a while loop:

for count < 10 {
	count++
}

The condition is checked before each iteration, just like while (count < 10) in C or Java.

How do I write while(true) in Go?

Write for with nothing after it: for { ... }. It loops until a break, return, panic or os.Exit ends it. for true { ... } also compiles, but for { } is the idiomatic form.

How do I write a do-while loop in Go?

Use an infinite loop and put the condition check at the end of the body:

for {
	// body runs at least once
	if !condition {
		break
	}
}

The body always runs once before the condition is tested, which is what do-while means.

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED