How do you link to another package's identifier from inside a Go doc comment?
answer
- no markup language, just conventions
- brackets around the identifier
- the package must be imported or fully pathed
- a broken one just stays as text
- one heading level, marked with #
basics
~20 sPut the identifier in square brackets: [io.Writer] for another package, [NewSession] for one in the same package. The package part must be one the file imports or a full import path; text that does not resolve is simply left as written.
solid answer
~50 sDoc links are written as bracketed identifiers inside the comment: `[NewSession]` for something in the same package, `[io.Writer]` or `[*bytes.Buffer]` for another package, and a method is written as the type name, a dot, and the method name. The package part is either the name the file imports it under or a full import path, and if the target cannot be resolved the tools leave the text alone rather than failing — so an unresolved link looks like stray brackets in the rendered output. The same doc comment syntax gives you `# Heading` lines to break a long comment into sections, indented lines for code blocks, `-` bullets for lists, and link definitions of the form `// [text]: https://example.com` collected at the end of the comment. `gofmt` normalises all of it, so write it roughly and let the formatter settle the layout.
code
go · 11 lines// Package console renders an interactive admin terminal for internal services.
//
// # Lifecycle
//
// Create a session with [NewSession] and close it to restore the terminal.
// Output is written to any [io.Writer]; a [*bytes.Buffer] is handy in tests.
//
// See the [operator runbook] before enabling destructive commands.
//
// [operator runbook]: https://example.com/runbook
package consolego deeper
Know that bracketed identifiers become links and that there is no Markdown here — just brackets, # headings, indented code blocks and simple lists. Write one and check it with go doc.
Explain resolution: the short package name works only if the file imports it, a full import path always works, and an unresolvable link is silently left as literal text rather than reported.
Show that you verify rendered output rather than trusting the source, and that you treat the first gofmt reformat of an old tree as a separate cosmetic commit so it does not hide behavioural changes in review.
Own the standard: decide how much structure a package overview is allowed to grow before it should become separate documentation, and keep link discipline consistent across a library other teams navigate.
## The syntax exists, and it is small Go doc comments are plain text with a handful of conventions, formalised in Go 1.19 when `gofmt` began reformatting doc comments into a canonical shape. There is no markup language to learn; there are five things. ### 1. Doc links A bracketed identifier becomes a link to that declaration. ```go // A Session is a live admin console attached to one terminal. // // Create one with [NewSession]. The writer it is given may be any // [io.Writer]; a [*bytes.Buffer] is convenient in tests. ``` The forms are `[Name]` for a declaration in the same package, `[Name.Method]` for a method on a local type, `[pkg.Name]` and `[pkg.Name.Method]` for another package, and a leading star is allowed — `[*bytes.Buffer]` — so the link reads naturally where a pointer type is meant. The package part must be resolvable: either the name the current file imports the package under, or a full import path such as `[golang.org/x/text/unicode/norm.NFC]` when the package is not imported. This is the detail people trip over — a link to a package you do not import, written with just its short name, does not resolve. And when a link does not resolve, nothing breaks. The tools leave the text exactly as you typed it, brackets included. That is a friendly failure mode for a build but an unfriendly one for a reader, because a typo shows up as literal brackets in the published documentation rather than as an error anyone gets told about. Reading the rendered output is the only check. ### 2. Headings A line whose text begins with `#` and a space is a heading: ```go // Package console renders an interactive admin terminal. // // # Lifecycle // // Every session must be closed to restore the terminal state. // // # Concurrency // // A session is owned by the goroutine that created it. ``` One `#` only — there is a single heading level, which is a deliberate limit on how much structure a comment can grow. Headings are worth it for a package comment with genuinely separate sections and are noise on a three-line function comment. ### 3. Lists An indented line starting with a bullet (`-`, `*`, `+`) or with a number followed by a period or bracket becomes a list item. A list must be separated from the paragraph above it by a blank comment line, and continuation lines are indented under the item. ### 4. Code blocks Any span of indented lines is rendered pre-formatted. This is how you show a short usage sketch or a sample of output inside a comment. Worth remembering: that text is *never compiled*, so it is the part of a doc comment most likely to be quietly wrong a year later — which is why a genuinely important usage sketch is better written as a runnable example function instead. ### 5. URL links Web links use a definition at the end of the comment: ```go // See the [operator runbook] before enabling destructive commands. // // [operator runbook]: https://example.com/runbook ``` The definitions are collected at the bottom of the comment, so the prose stays readable in the source. ## gofmt owns the layout Since the syntax was formalised, `gofmt` rewrites doc comments into a canonical form: it normalises list indentation, moves link definitions to the end, tidies heading spacing, and reflows nothing else. Two practical consequences. First, you do not have to get the whitespace right by hand — write it approximately and run the formatter. Second, the first time a repository formats with a modern toolchain, doc comments across the tree will show diffs; that is the reformatting, not a change of meaning. ## How much of this to use The honest answer is: links liberally, headings sparingly, everything else when the content demands it. Links are pure benefit — they cost one pair of brackets and turn a mention of a type into navigation, which matters most in exactly the place documentation is weakest, the sentence that says "pass this to the writer" without saying which writer. Headings and lists earn their place in a package overview and almost never in a comment on a single function. And a comment that has grown enough structure to need three headings and two lists is often a signal that the package needs a separate overview rather than a bigger comment. ## Checking your work Run `go doc` on the package or the symbol and read what comes out. Rendered output is where an unresolved link, a list that did not become a list, or a heading that did not take announce themselves; none of them is visible from staring at the `//` lines in an editor.
- What happens when a doc link's target cannot be resolved?The text is left exactly as written, brackets and all, and nothing reports an error. No build fails and no tool warns, so a mistyped identifier or a link to a package the file does not import shows up only as stray brackets in the rendered documentation. Reading the output of `go doc` is the only way to catch it.
- How do you link to a package the current file does not import?Write the full import path inside the brackets instead of the short package name, for example `[golang.org/x/text/unicode/norm.NFC]`. The short-name form resolves against the file's imports, so it silently fails to link for a package that is only mentioned in prose.
- What did gofmt start doing to doc comments, and what should a team expect the first time they format with a modern toolchain?It reformats them into a canonical shape: list indentation normalised, link definitions moved to the end of the comment, heading spacing tidied. The first run across an old repository produces a wide comment-only diff. It is cosmetic, so land it as its own commit rather than mixed into a behavioural change.
- When are headings in a doc comment worth using?In a package overview that genuinely has sections — lifecycle, concurrency, migration notes — where a reader is scanning for one of them. On a comment for a single function they are noise: the comment should be short enough that structure adds nothing. There is only one heading level, which is a hint about the intended scale.
saying these in an interview costs you the question
- Assumes doc comments accept full Markdown syntax
- Expects an unresolved doc link to be reported as an error
- Links a package by short name without importing it
- Uses ## or ### expecting nested heading levels
- Writes URLs inline expecting them to become named links
- Hand-aligns list indentation that gofmt will rewrite anyway