Packages and Exported Identifiers
How Go organizes code into packages, and its capitalization-based visibility rule.
What you'll learn
- Explain how Go groups files into packages
- State Go's rule for exported (public) vs unexported (private) identifiers
- Read a Go import path and identify the package it refers to
Explanation
Every Go source file belongs to exactly one package, declared at the top of the file (package main, package util, and so on). Every .go file in the same directory must declare the same package name -- a package is really a directory's worth of files sharing one namespace.
Go's visibility rule is refreshingly simple and has no dedicated keyword: an identifier (a function, type, variable, or struct field) whose name starts with an uppercase letter is exported (visible outside its package); one starting lowercase is unexported (package-private). func Add(...) is callable from other packages; func add(...) is not.
A Go module (declared in a go.mod file) is a collection of related packages versioned and distributed together -- when you import "github.com/someuser/somemodule/somepackage", you're pulling in one package from someone else's module.
This capitalization convention means you can often tell a lot about a package's public API just by scanning for capitalized names, without needing separate public/private keywords cluttering every declaration.
Guided lab
Predict: Exported vs unexported identifiers
This shows two files from the same package (comments mark the file boundary). Predict what main.go prints, and note the one line that would NOT compile if uncommented.
// file: util/util.go
package util
func Double(n int) int {
return double(n) * 2
}
func double(n int) int {
return n * 2
}
// file: main.go
package main
import (
"fmt"
"example.com/app/util"
)
func main() {
fmt.Println(util.Double(3))
// fmt.Println(util.double(3)) // would NOT compile: double is unexported
}Stuck? Get a hint.
Common mistakes
- Trying to call a lowercase (unexported) function from a different package and being confused by the compile error.
- Putting files with different `package` declarations in the same directory -- every file in one directory must share the same package name.
- Confusing a Go module (versioned collection of packages, from go.mod) with a single package (one directory's worth of files).
Knowledge check
Takeaway
Capitalize a name to export it outside its package; lowercase keeps it package-private -- no separate keyword needed.
Summary
Files sharing a directory form one package; capitalization alone determines export visibility; a module (go.mod) versions a collection of packages.
References
Your notes
Notes save automatically.
Finished this lesson?
Mark it complete to track your progress and schedule a future review.
AI tutor
The optional AI tutor isn't enabled in this deployment. All lessons, exercises, quizzes, and search work fully without it.