Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Maps & Structs  ›  Lesson

The Comma-Ok Idiom

Comma-Ok Idiom 12 minAdding a second boolean result to a map lookup, a type assertion or a channel receive, as in v, ok := m[k], tells you whether a real value was found instead of a default.

The Comma-Ok Idiom

tally gains a feature: it remembers the line on which each word last appeared, with lines numbered from 0. Now lastLine["go"] returns 0 — but did "go" appear on the first line, or never at all? The zero value that made counting easy has become ambiguous. Go's answer is a second return value.

The rule

Ask for ok whenever zero could be a real answer.

Any map lookup can return two values:

line, ok := lastLine["go"]
  • line is the stored value, or the zero value if the key is absent.
  • ok is true if the key is present, false if not — regardless of what the value is.
lastLine := map[string]int{"tally": 0}

n, ok := lastLine["tally"] // 0 true  — present, on line 0
m, ok2 := lastLine["go"]   // 0 false — absent

The usual shape puts it in an if header, so the variables live only where they matter:

if line, ok := lastLine[w]; ok {
	fmt.Printf("%q last seen on line %d\n", w, line)
} else {
	fmt.Printf("%q never appears\n", w)
}

If you only care about presence, discard the value: _, seen := lastLine[w].

The same two-value pattern — hence the name "comma ok" — appears in two other places you will meet later:

  • Type assertions: s, ok := v.(string). Without ok, a wrong type panics; with it, you get ok == false instead.
  • Channel receives: v, ok := <-ch. ok is false once the channel is closed and empty.

The shortcut

Before trusting a lookup, ask "could the zero value also be a genuine value?" If yes — a count that can be 0, a line number, a bool flag stored as false — use comma-ok. If zero can only mean "absent", the single-value form is fine.

Was "go" really on line 0?Step 1 of 4
  1. The ambiguous read

    lastLine["go"] is 0. That fits both "line 0" and "missing".

Drills

Answer fast — trust the rule.

quick drill

m := map[string]int{"a": 0}. What does _, ok := m["a"] give for ok?

quick drill

m := map[string]int{"a": 0}. What are v, ok := m["b"]?

quick drill

var x any = 42. What happens with s := x.(string), without ok?

quick drill

For which map is the single-value lookup m[k] already unambiguous?

Remember

  • Ask for ok whenever zero could be a real answer.
  • Shortcut: "could zero be genuine?" Yes → v, ok := m[k] and branch on ok.
  • Trap: type assertions without ok panic; map lookups without ok just return zero.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainZero or missing?

tally keeps lastLine := map[string]int{} recording the line where each word last appeared, and lines are numbered from 0. Explain why lastLine["go"] == 0 cannot tell you whether "go" appeared, and show how the comma-ok idiom solves it.