Packages, modules and tooling · 3 MIN READ

A capital letter is the access modifier

Control visibility without keywords, and name things accordingly.

An identifier starting with an upper-case letter is visible outside its package; anything else is not. There is no public, private or protected.

Because the name carries the visibility, renaming is an API change, and Go's naming conventions get unusually strict: no stuttering (build.Runner, not build.BuildRunner), no Get prefix on getters, and short names for short-lived variables.

SEE THE IDEA

Capitalization marks the package boundary

  1. 01

    Exported

    go
    type Config struct { Port int }

    Names beginning with uppercase are visible

  2. 02

    Internal

    go
    func parse()

    Lowercase names remain package-local

  3. 03

    Access

    go
    config.Port

    An exported type may still have private fields

Export is per identifier, including each struct field and method.

In practice

Give exported names useful documentation and keep implementation helpers private. Visibility applies between packages, not between files in the same package. Standard-library encoders such as encoding/json normally inspect exported struct fields, so field visibility also affects serialization.

Watch out

An exported struct type does not automatically export its lowercase fields.

Official reference ↗

Work through the exercise

go
// Runner executes one build.
type Runner struct {
	workdir string
}

func NewRunner(workdir string) *Runner {
	return &Runner{workdir: workdir}
}
Try it yourself

Trace each value and write down your reasoning. Copy the source into GopherForge or your local Go environment to compile and check it. This web page does not execute your code or send it to a compiler service.

Progress stays in this browser. No account needed.