← Go EnglishChapter 12 of 13

Packages and Modules

## Learning Objectives - Understand Go packages - Create and use modules - Import packages correctly - Organize code effectively - Work with the go.mod file ## Packages ### What is a Package? A package is a collection of Go source files in the same directory. ### Package Declaration ```go package main // Executable package package utils // Library package ``` ### Package Names ```go package main // Executable package math // Library (math functions) ``` ## Project Structure ### Standard Layout ```text myproject/ ├── go.mod ├── main.go ├── utils/ │ └── helpers.go └── models/ └── user.go ``` ### Package Names Match Directory ```text utils/helpers.go -> package utils models/user.go -> package models ``` ## Modules ### What is a Module? A module is a collection of Go packages versioned together. ### Creating a Module ```bash go mod init example.com/myproject ``` ### go.mod File ```go module example.com/myproject go 1.21 require ( github.com/some/pkg v1.2.3 ) ``` ## Imports ### Basic Import ```go import "fmt" func main() { fmt.Println("Hello") } ``` ### Multiple Imports ```go import ( "fmt" "math" "strings" ) func main() { fmt.Println(math.pi) fmt.Println(strings.ToUpper("hello")) } ``` ### Import with Alias ```go import ( f "fmt" // Alias m "math" // Alias ) func main() { f.Println(m.pi) } ``` ### Dot Import ```go import . "fmt" // Avoid: pollutes namespace func main() { Println("Hello") // No prefix } ``` ### Blank Import ```go import _ "database/sql" // Register driver only ``` ## Creating Packages ### utils/helpers.go ```go package utils func Reverse(s string) string { runes := []rune(s) for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 { runes[i], runes[j] = runes[j], runes[i] } return string(runes) } func UpperCase(s string) string { return strings.ToUpper(s) } ``` ### main.go ```go package main import ( "fmt" "example.com/myproject/utils" ) func main() { fmt.Println(utils.Reverse("hello")) fmt.Println(utils.UpperCase("hello")) } ``` ## Visibility Rules ### Exported vs Unexported ```go package utils const MaxSize = 100 // Exported (capitalized) const minSize = 10 // Unexported (lowercase) func PublicFunc() {} // Exported func privateFunc() {} // Unexported ``` ### Access from Outside ```go import "example.com/myproject/utils" utils.MaxSize // OK utils.PublicFunc() // OK // utils.minSize // ERROR: not accessible // utils.privateFunc() // ERROR: not accessible ``` ## init Function ### Automatic Execution ```go package utils var config string func init() { config = "default" } ``` ### Multiple init Functions ```go package main func init() { fmt.Println("First init") } func init() { fmt.Println("Second init") } ``` ### init Order 1. Imported packages initialized first 2. Package-level variables initialized 3. init() functions run in declaration order ## Standard Library Packages ### Common Imports ```go import "fmt" // Formatted I/O import "os" // Operating system import "io" // I/O primitives import "bufio" // Buffered I/O import "strings" // String utilities import "strconv" // String conversion import "time" // Time operations import "math" // Math functions import "log" // Logging import "errors" // Error handling ``` ### net/http ```go import "net/http" func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello")) }) http.ListenAndServe(":8080", nil) } ``` ### encoding/json ```go import "encoding/json" type Person struct { Name string `json:"name"` Age int `json:"age"` } func main() { p := Person{Name: "Alice", Age: 30} jsonBytes, _ := json.Marshal(p) fmt.Println(string(jsonBytes)) } ``` ## External Packages ### go get ```bash go get github.com/gin-gonic/gin go get github.com/stretchr/testify ``` ### Version Specification ```go require ( github.com/gin-gonic/gin v1.9.1 github.com/stretchr/testify v1.8.4 ) ``` ### go.sum Automatically generated and tracked. ## Module Commands ### Common Commands ```bash go mod init example.com/project # Initialize module go mod tidy # Clean up dependencies go mod download # Download dependencies go mod graph # Show dependency graph go mod why github.com/pkg # Explain why dependency ``` ### go mod tidy ```bash # Removes unused dependencies # Adds missing dependencies # Updates go.mod and go.sum go mod tidy ``` ## vendoring ### Create Vendor ```bash go mod vendor ``` ### Directory Structure ```text project/ ├── go.mod ├── go.sum ├── vendor/ │ └── github.com/ │ └── pkg/ │ └── *.go └── main.go ``` ### Using Vendor ```bash go build -mod=vendor ``` ## Testing Packages ### Basic Test ```go package utils func Add(a, b int) int { return a + b } ``` ### utils_test.go ```go package utils import "testing" func TestAdd(t *testing.T) { result := Add(2, 3) if result != 5 { t.Errorf("Add(2, 3) = %d, want 5", result) } } ``` ### Run Tests ```bash go test ./... # Run all tests go test -v ./... # Verbose output go test -cover ./... # Show coverage ``` ## Code Organization Tips ### Single Module per Project ```text myproject/ ├── go.mod ├── cmd/ │ └── app/ │ └── main.go ├── internal/ │ ├── handlers/ │ ├── models/ │ └── services/ ├── pkg/ │ └── utils/ └── api/ ``` ### internal Package Packages named `internal` are only importable by parent directories. ```text myproject/ ├── internal/ │ └── utils/ │ └── helpers.go └── cmd/ └── app/ └── main.go // Can import internal/utils ``` ## Summary - Packages group related Go source files - Modules are versioned collections of packages - `go.mod` defines module name and dependencies - Exported identifiers start with uppercase - `init()` runs automatically before main - Use `go get` to add dependencies - `go mod tidy` manages dependencies - Test files end with `_test.go`

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →