skip to content

When should a Go Example use // Unordered output: instead of // Output:?

level: middleimportance: nice to knowfreq 24%

answer

  1. map iteration order is not fixed
  2. one line per item printed
  3. both sides get sorted first
  4. count and duplicates still matter

basics

~20 s

When the example prints one line per item and the line order is not guaranteed, such as ranging over a map. With // Unordered output: the runner sorts the printed lines and the expected lines before comparing, so order stops mattering but content and count still do.

solid answer

~40 s

Use it when the *set* of lines is deterministic but their order is not — printing one line per key while ranging over a map is the standard case, since Go deliberately randomises map iteration order. `// Unordered output:` makes the runner split both the captured output and the expected block into lines, sort each, and compare the results, so a differently ordered run still passes while a missing, extra or duplicated line still fails. It is not a licence for non-determinism generally: if the *content* varies between runs, no output block will help. The alternative worth weighing is sorting the keys yourself and keeping a plain `// Output:` block, which is often better because the example is documentation and a reader benefits from seeing stable, predictable output.

code

go · 9 lines
go
func ExampleQuery_Keys() {
	q := Query{"b": {"2"}, "a": {"1"}}
	for k := range q {
		fmt.Println(k)
	}
	// Unordered output:
	// a
	// b
}

go deeper

for a junior

Know that ranging over a map gives keys in an unspecified order, and that // Unordered output: is the block to use when an example prints one line per key. Remember it still has to be the last comment in the body.

for a middle

Explain the mechanism precisely: both the printed lines and the expected lines are sorted and then compared, so order is relaxed while count, duplicates and each line's text stay strict.

for a senior

Show the judgment call. Decide when to sort the values in the example and keep a plain // Output: block because the documentation reads better, and recognise when flakiness is in a line's content, where no output block can help.

for a principal

Own what the team's published examples promise. Decide whether examples may present unspecified ordering to readers at all, and hold the line that an unordered block is not a way to launder genuine non-determinism into a passing check.

## The problem it solves An example is checked against fixed text, and fixed text implies a fixed order. That works for almost everything an example prints — except iteration over a map, whose order Go randomises on purpose so that no program can come to depend on it. An example that ranges over a two-key map and prints one line per key will pass and fail alternately with an ordinary `// Output:` block. `// Unordered output:` exists for exactly that shape: ```go func ExampleQuery_Keys() { q := Query{"b": {"2"}, "a": {"1"}} for k := range q { fmt.Println(k) } // Unordered output: // a // b } ``` ## What the comparison actually does It is a sorted line comparison, not a subset test. The runner takes the captured stdout and the expected block, splits both into lines, sorts each set of lines, and compares the sorted sequences. The consequences are worth stating precisely: - Order is irrelevant. - Line **count** still matters. An extra printed line fails. - **Duplicates** still matter. Two identical printed lines require two identical expected lines. - Each line's own content must still match exactly. If a line's text varies between runs, unordered comparison does not save you. So it relaxes exactly one dimension — the order lines appear in — and keeps everything else as strict as `// Output:` is. ## When it is the wrong tool It is tempting to reach for it whenever an example is flaky, and that is usually a misdiagnosis. If the flakiness comes from a value that differs per run — a duration, a generated identifier, a memory address — the printed lines themselves are not stable and no sorted comparison will help. The fix there is to stop printing the unstable value, or to print something derived from it that is stable, such as a boolean or a length. It is also the wrong tool when the output is only *incidentally* unordered. If you are printing map keys, you can sort them into a slice and print in a defined order, then use a plain `// Output:` block. That version is usually the better example for the same reason it is a slightly worse test: the reader sees one predictable result, and the documentation reads like something they could reproduce line for line. The unordered form quietly tells a reader "the order you see here is not real", which is honest but less useful when the order genuinely does not matter to them. A reasonable rule: if the ordering is a detail of the data structure you happen to be iterating, sort it and use `// Output:`. If the ordering is genuinely part of what you are demonstrating being unspecified — the whole point of the example is that these values arrive in no particular order — use `// Unordered output:`. ## Mechanics shared with the ordinary form Everything else about the output block is unchanged. The comment must still be the last comment in the function body, or the example is skipped and never checked. Only `os.Stdout` is captured. Surrounding whitespace is trimmed. The single-line form is not useful here — an unordered block with one line is just an ordinary block — so it is always written as a multi-line block. ## A note on line-shaped output Because the comparison is line-based, an example whose unordered content is not naturally one item per line will not benefit. If you print a whole map with `fmt.Println(m)` you get a single line whose *interior* ordering the map printing does define — Go's map formatting prints keys in sorted order — so that case does not need the unordered form at all. The unordered form is for output you produced yourself, one line at a time, in whatever order the iteration handed the items to you.

  • Does an unordered output block tolerate an extra printed line?
    No. Both sides are sorted and then compared as whole sequences, so an extra line, a missing line or a wrong number of duplicates all fail. Only the order is relaxed; content and count are checked exactly as strictly as with an ordinary output block.
  • When is sorting the values yourself and using // Output: the better choice?
    Whenever the ordering is an accident of the data structure rather than part of the lesson. Collecting keys into a slice, sorting it and printing in order gives the reader one predictable result to compare against, which reads better as documentation — and the example is still fully checked, just against a fixed sequence.
  • An example prints a duration and fails intermittently. Will the unordered form fix it?
    No. That flakiness is in the content of a line, not in the order of lines, and sorting does not make an unstable value stable. Either stop printing the varying value or print something derived and stable from it, such as whether it fell under a threshold.

saying these in an interview costs you the question

  • Treating it as a general cure for flaky examples
  • Believing extra printed lines are tolerated
  • Thinking duplicate lines collapse before comparison
  • Using it for output whose values vary per run
  • Putting the unordered block anywhere but last in the body