Packages in Go

·

3 min read

A package in Go is a collection of source files in the same directory that are compiled together. They serve as the building blocks for code organization and re-usability in Go programs. Each source file must declare its package name at the top, and all files in the same directory must belong to the same package.

Package Declaration and Naming Conventions

package main  // Used for executable programs
package math  // Used for reusable libraries

Best practices for package naming:

  • Use lowercase, single-word names

  • Avoid underscores or camelCase

  • Make names descriptive and concise

  • Package name should match the directory name

  • Use meaningful names that describe the package's purpose

Main Package

The main package is special in Go. It indicates that this package will compile into an executable rather than a library and does not take any argument. Every executable Go program must have a main package with a main() function:

package main

func main() {
    // Program entry point
}

Library Packages

Any package other than main is a library package. These packages can be imported and used by other packages:

package geometry

func CalculateArea(width, height float64) float64 {
    return width * height
}

Simple rule for package visibility:

  • Names beginning with an uppercase letter are exported (visible outside the package)

  • Names beginning with a lowercase letter are unexported (private to the package)

Example:

package math

// Exported function - accessible from other packages
func Calculate(x int) int {
    return calculate(x) * 2
}

// Unexported function - only accessible within this package
func calculate(x int) int {
    return x * x
}

Importing Packages

Go provides several ways to import packages:

Single Import

import "fmt"

Multiple Imports

import (
    "fmt"
    "strings"
    "math/rand"
)

Import with Alias

import (
    f "fmt"
    s "strings"
)

Package Management with Go Modules

Modern Go programs use modules for dependency management. Here's how to work with them:

# Initialize a new module
go mod init example.com/myproject

# Add dependencies
go get github.com/some/package

# Clean up dependencies
go mod tidy

The go.mod file:

module example.com/myproject

go 1.23

require (
    github.com/some/package v1.2.3
    github.com/another/dep v2.0.0
)

Creating and Organizing Packages

myproject/
├── go.mod
├── main.go
├── internal/
│   ├── database/
│   │   └── db.go
│   └── auth/
│       └── auth.go
└── pkg/
    └── utilities/
        └── helper.go

Best practices:

  1. Use internal/ for private packages

  2. Use pkg/ for public packages

  3. Keep related functionality together

  4. Follow the principle of separation of concerns

Working with Internal Packages

The internal directory has special meaning in Go. Any package inside an internal directory can only be imported by code in the parent directory or its subdirectories:

myapp/
├── internal/
│   └── secret/
│       └── secret.go
└── main.go  // Can import "myapp/internal/secret"

Common Standard Library Packages

Go's standard library is rich with useful packages:

  1. fmt - Formatted I/O

  2. strings - String manipulation

  3. io - Basic I/O interfaces

  4. os - Operating system functionality

  5. net/http - HTTP client and server

  6. encoding/json - JSON encoding/decoding

  7. time - Time and duration functions

  8. context - Context management