Packages in Go are the primary building block for organizing code and managing scopes. Historically, Go chose a simple model for imports and folder hierarchies to make programming transparent and avoid ambiguities with dependency resolution, as seen in C/C++ and Java. The problem Go addresses is creating a clear project structure, preventing name conflicts, and ensuring modules are independent of each other.
Problem: Without a unified approach to organization, applications cannot scale; duplication, name conflicts, and cyclic dependencies arise. It is important to explicitly manage the visibility of objects.
Solution: Each directory contains a file with the package (package somepackage), and the directory name and package name coincide as per best practices. Imports are handled via the import keyword, and only objects with capitalized names are exported. Dependency management is done through go modules (go.mod).
Example of structure and import:
// internal/mathops/add.go package mathops func Add(a, b int) int { return a + b } // main.go package main import ( "fmt" "myservice/internal/mathops" ) func main() { fmt.Println(mathops.Add(2, 3)) }
Key features:
Can multiple different packages be declared in one directory?
No, all files in a directory must belong to one package.
Will functions be exported if their name starts with a capital letter, while the package is named with a lowercase letter?
Yes, export depends only on the first letter of the object’s name (function, type, variable), not on the package name.
Can a package be imported with a different alias, and will that affect the visibility of functions?
Yes, it can. The alias only affects the name used to refer to the package, but does not change the visibility:
import mymath "myservice/internal/mathops" mymath.Add(1,2)
A developer puts all functions into one file "utils.go" in the main package, not separating business logic into distinct packages.
Pros:
Cons:
Business logic, utilities, handlers, and data models are moved into independent packages: mathops, user, storage, api. Imports are strictly purposeful, and each package is tested independently.
Pros:
Cons: