How do Go Example function names bind an example to a specific type or method?
answer
- the name is the only binding
- underscore separates type from method
- case of the next letter decides
- lower-case tail is a label
basics
~20 sBy the name alone. Example documents the package, ExampleF a function or type F, and ExampleT_M the method M on type T. Any of those may carry a trailing lower-case suffix, such as ExampleParse_relativePath, to give one symbol several examples.
solid answer
~40 sThe name is the only binding — there is no annotation. `func Example()` documents the package as a whole; `func ExampleCanonical()` attaches to the function or type `Canonical`; `func ExampleQuery_Add()` attaches to the method `Add` on type `Query`, the underscore separating receiver type from method. Any of those forms may take a further suffix that must begin with a lower-case letter — `ExampleParse_relativePath` — which is how you attach several examples to one symbol; the suffix becomes the example's label in the rendered documentation. Case is what disambiguates: after an underscore, an upper-case start reads as a method name, a lower-case start reads as a label. The identifier named must actually exist and be exported, and `go vet` reports an example whose name refers to nothing.
code
go · 9 linesfunc Example() { /* the package as a whole */ }
func ExampleCanonical() { /* the Canonical function */ }
func ExampleQuery() { /* the Query type */ }
func ExampleQuery_Add() { /* Query's Add method */ }
func ExampleQuery_Add_repeatedKey() { /* a second Add example */ }go deeper
Memorise the four shapes: Example for the package, ExampleF for a function, ExampleT for a type, ExampleT_M for a method. Be able to write the right name for a method on a given type without hesitating.
Explain the case rule that separates a method name from a label after the underscore, and why go vet is what catches a misnamed example. Show how suffixes let one symbol carry several separately checked examples.
Demonstrate that you use naming as a documentation decision: which exported symbols deserve examples, which edge case earns its own suffixed example, and why an example for an unexported helper belongs in a plain test instead.
Own the convention across a package other teams depend on. Decide what counts as documented enough to release, whether go vet failing the build is the enforcement you want, and how examples are kept honest through renames.
## The name is the whole API Go has no annotation that says "this example documents that function". The tooling derives the association purely from the function's name, so the naming grammar is worth memorising exactly. | Name | Attaches to | | --- | --- | | `Example` | the package as a whole | | `ExampleCanonical` | the exported function or type `Canonical` | | `ExampleQuery` | the exported type `Query` | | `ExampleQuery_Add` | the method `Add` on type `Query` | | `ExampleCanonical_trailingSlash` | a second example for `Canonical`, labelled `trailingSlash` | | `ExampleQuery_Add_repeatedKey` | a second example for `Query.Add`, labelled `repeatedKey` | The rule underneath the table: after the `Example` prefix, an underscore introduces either a **method name** or a **suffix**, and the case of the first letter decides which. `Add` starts upper-case, so `ExampleQuery_Add` is a method example. `repeatedKey` starts lower-case, so it is a label. That is also why `ExampleQuery_add` does *not* document a method named `add` — it reads as the type `Query` with the label `add`. ## Why the suffix exists One example per symbol is often not enough. A URL-canonicalising function deserves one example for the ordinary case and another for the surprising one — an empty query, a duplicated key, a relative path. Without suffixes you would be stuck with a single monolithic example that prints six lines and teaches nothing clearly. With them, each case is a separate, separately checked function, and the documentation page lists them under the symbol with the suffix as a heading. The suffix is free-form as long as it starts lower-case. It is a label for a human reader, so write it as a phrase describing the case, not as a counter: `_emptyQuery` beats `_2`. ## The first letter after the prefix An essential trap: the character immediately after `Example` must not be lower-case. `func Examplecanonical()` is not recognised as an example at all — it is an ordinary function in the test binary, and since nothing calls it, it never runs and never fails. `go vet` reports this as a malformed name, which is one of the reasons to keep `go vet` in the build. ## The named identifier must exist An example whose name points at a symbol the package does not have is a documentation lie: nothing renders it under that symbol, and the check it appears to be performing is unattached. `go vet`'s test checks catch this too, reporting that the example refers to an unknown identifier, along with malformed suffixes and a signature that is not niladic. The binding is to *exported* API. An example for an unexported helper has nowhere to render on the documentation page, which is a reasonable hint that such a case belongs in an ordinary test function rather than an example. ## Where the file lives Examples live in `_test.go` files, so they never ship in the package build, but they are shown to readers as if they were normal calling code. That is the point: the reader should see the package used the way they will use it. Many authors write examples in the package's external test package so the example is forced to go through the exported surface — an example that reaches into an unexported field would demonstrate something no caller can do. ## Rendering `go doc` shows examples attached to whatever symbol you asked about, and the package documentation page groups them under their symbols with the suffix as the sub-heading. That rendering is the reason the naming rules are strict rather than advisory: the tool has no other information to route the example with. When an example does not appear where you expected it on the page, the name is almost always the reason — a lower-case first letter, a suffix that starts upper-case and got read as a method, or an identifier that no longer exists after a rename.
- What does ExampleQuery_add document, given that the type Query has no method add?The type `Query`, with `add` as a label. Because the text after the underscore starts with a lower-case letter it is read as a suffix, not as a method name, so the example renders as a second example for the type. That silent reinterpretation is why a method example on an unexported method cannot be expressed at all.
- What happens to a function named Examplecanonical in a _test.go file?Nothing runs it. The character after `Example` must not be lower-case for the tooling to recognise the function as an example, so it becomes an ordinary uncalled function in the test binary — compiled, never executed, never rendered. `go vet` flags it as a malformed name, which is the practical way it gets caught.
- How do you give one function several examples that all get checked?Write one function per case with distinct lower-case suffixes: `ExampleCanonical_emptyQuery`, `ExampleCanonical_trailingSlash`. Each is a separate function with its own `// Output:` block, so each is checked independently, and the documentation page lists them under the symbol with the suffix as a heading.
saying these in an interview costs you the question
- Thinking an annotation or comment attaches the example
- Writing ExampleQuery_add and expecting a method example
- Starting the name with a lower-case letter after Example
- Using numeric suffixes like _1 and _2 as labels
- Naming an identifier the package does not actually export