Lesson 10 of 12
Packages, Modules & the Standard Library
Learn how Go code is organized into and , and how to use the . A single go.mod file and the go command handle building and dependencies.
# Start a module — the path is normally the repo URL
go mod init github.com/you/myapp
# Add a dependency (or just import it and run go mod tidy)
go get github.com/google/uuid
go mod tidy # add what is imported, remove what is not
go run ./cmd/server # compile and run
go build ./... # build everything
go test ./... # test everything
go vet ./... # catch suspicious constructs
gofmt -w . # formatting is not a debate in Go
# A conventional layout
# myapp/
# go.mod
# cmd/server/main.go package main — the entry point
# internal/store/store.go importable ONLY inside this module
# pkg/api/client.go intended for outside consumers
# go.sum checksums, commit this file// internal/store/store.go
package store // package name = directory name, lowercase, no underscores
import "errors"
// Exported: capital letter. Unexported: lowercase, package-private.
var ErrMissing = errors.New("store: key missing")
type Store struct {
data map[string]string // unexported field — callers cannot touch it
}
func New() *Store { // constructor convention: New / NewX
return &Store{data: make(map[string]string)}
}
func (s *Store) Set(key, value string) { s.data[key] = value }
func (s *Store) Get(key string) (string, error) {
v, ok := s.data[key]
if !ok {
return "", ErrMissing
}
return v, nil
}
// cmd/server/main.go
package main
import (
"fmt"
"github.com/you/myapp/internal/store"
)
func main() {
s := store.New()
s.Set("greeting", "hello")
v, _ := s.Get("greeting")
fmt.Println(v)
}package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
"strings"
"time"
)
type Todo struct {
ID int `json:"id"`
Title string `json:"title"`
Done bool `json:"done,omitempty"` // struct tags control JSON names
}
func main() {
// encoding/json
data, _ := json.Marshal(Todo{ID: 1, Title: "Learn Go"})
fmt.Println(string(data)) // {"id":1,"title":"Learn Go"}
var t Todo
json.Unmarshal([]byte(`{"id":2,"title":"Ship it","done":true}`), &t)
// net/http server in six lines — no framework required
mux := http.NewServeMux()
mux.HandleFunc("GET /todos/{id}", func(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(Todo{ID: 1, Title: "todo " + id})
})
srv := &http.Server{Addr: ":8080", Handler: mux, ReadTimeout: 5 * time.Second}
go srv.ListenAndServe()
// strings, os and friends
fmt.Println(strings.Join([]string{"a", "b"}, "-"))
fmt.Println(strings.HasPrefix("golang", "go"))
fmt.Println(os.Getenv("HOME"))
}Finished reading?Mark it done to track your progress.
Tip: use the ← and → keys to move between lessons.