Packages and Imports
Go organises code into packages. A package is a directory containing one or more .go files that share the same package declaration. Packages are the fundamental unit of code organisation and reuse in Go.
Package Declarations
Every Go file starts with a package declaration:
package main // executable package
// or
package mathutil // library packagePackages with package main are compiled into executables. Any other name produces a library that other packages can import.
Exported Names
An identifier starting with an uppercase letter is exported — visible to other packages. Lowercase identifiers are package-private:
package mathutil
// Exported — other packages can use this
func Add(a, b int) int {
return a + b
}
// Unexported — only visible within this package
func helper(n int) int {
return n * 2
}Idiomatic Go: Go enforces encapsulation through capitalisation alone — no
public,private, orprotectedkeywords are needed.
Importing Packages
Use the import keyword to bring packages into scope. Group multiple imports in a single parenthesised block:
package main
import (
"fmt"
"math"
"strings"
)
func main() {
fmt.Println(math.Sqrt(16)) // 4
fmt.Println(strings.ToUpper("hello")) // HELLO
}Import Aliases
Alias an import when names would conflict or when the default name is verbose:
package main
import (
"fmt"
mrand "math/rand"
crand "crypto/rand"
)
func main() {
fmt.Println(mrand.Intn(100))
buf := make([]byte, 16)
crand.Read(buf)
fmt.Printf("%x\n", buf)
}Blank Import
Importing a package solely for its side effects (usually init registration) uses _:
import _ "image/png" // registers the PNG decoderThe init Function
Each package may define one or more init functions. They run automatically, in order, after all variable initialisations in the package, and before main:
package main
import "fmt"
var greeting string
func init() {
greeting = "Hello from init!"
fmt.Println("init() called")
}
func main() {
fmt.Println(greeting)
}
// Output:
// init() called
// Hello from init!init functions cannot be called directly. Use them for one-time setup such as registering drivers, validating configuration, or seeding state.
Package Paths and the Standard Library
Standard-library packages are imported by their short path (e.g., "fmt", "net/http"). Third-party packages use a full module path:
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello from Go!")
})
http.ListenAndServe(":8080", nil)
}The internal Package Convention
A package placed in a directory named internal can only be imported by code in the parent directory tree. This enforces boundaries without requiring additional visibility modifiers:
myapp/
internal/
auth/ ← importable only within myapp/
api/
main.go
Key Takeaways
- A package is a directory of
.gofiles sharing the samepackagedeclaration. - Uppercase identifiers are exported; lowercase ones are package-private.
- Group imports in a parenthesised block; use aliases to resolve name conflicts.
initfunctions run once automatically; they cannot be called manually.- Use the
internaldirectory to enforce package-level encapsulation.