Packages
As a project grows, placing every source file in one directory becomes difficult to maintain.
Instead of:
main.go
helper.go
crypto.go
json.go
storage.go
parser.go
network.go
...Go organizes code into packages.
Each package has a single responsibility and groups related source files together.
Project Structure
Example:
myproject/
│
├── go.mod
├── main.go
│
└── calculator/
└── calculator.goThe directory calculator represents a package.
Defining a Package
calculator/calculator.go
package calculator
func Add(a, b int) int {
return a + b
}Every source file begins with a package declaration.
Importing a Package
main.go
package main
import (
"fmt"
"myproject/calculator"
)
func main() {
fmt.Println(calculator.Add(2, 3))
}Output:
5Import Paths
The import path is:
Module Name
+
Directory NameExample:
go.mod
module myprojectDirectory:
calculator/Import:
import "myproject/calculator"The import path is not simply the package name.
Package Names
Usually the directory name and package name are identical.
calculator/contains
package calculatorAlthough Go allows different names, matching them is the standard convention.
Packages as Namespaces
Every exported identifier belongs to its package.
Examples:
fmt.Println()
os.Args
json.Marshal()
calculator.Add()General pattern:
Package.IdentifierThis applies to:
-
Functions
-
Types
-
Variables
-
Constants
-
Interfaces
Exported Types
Suppose:
package calculator
type Book struct {
Title string
}In another package:
var book calculator.BookThe package name qualifies the type.
This is similar to namespaces in C++:
calculator::BookExported vs Unexported Identifiers
Go uses capitalization to determine visibility.
Exported:
func Add()
type Book struct {
Title string
}Accessible from other packages.
Unexported:
func subtract()
type Book struct {
pages int
}Accessible only inside the same package.
No public or private keywords are needed.
Accessing Struct Fields
Given:
type Book struct {
Title string
pages int
}This works:
book.TitleThis does not:
book.pagesBecause pages begins with a lowercase letter.
The same export rule applies to:
-
Functions
-
Methods
-
Types
-
Variables
-
Constants
-
Struct fields
Multiple Files in a Package
Example:
calculator/
add.go
subtract.go
multiply.goEach file begins with:
package calculatorGo combines all files in the package during compilation.
Package Aliases
Long package names can be shortened.
import calc "myproject/calculator"Usage:
calc.Add(2, 3)Standard Library Packages
Frequently used packages include:
fmtConsole output.
osOperating system interaction.
encoding/jsonJSON encoding and decoding.
crypto/aesAES encryption.
crypto/randCryptographically secure random numbers.
Common Beginner Mistakes
Wrong Import Path
Incorrect:
import "calculator"Correct:
import "myproject/calculator"The module name is part of the import path.
Forgetting Capitalization
func add()Cannot be accessed outside the package.
Use:
func Add()when the function is intended to be public.
Using Package Name Inside the Same Package
Inside package calculator:
Incorrect:
calculator.Add()Correct:
Add()Code inside a package refers to its own identifiers directly.
Confusing Package Name with Import Path
Import path:
myproject/calculatorPackage name:
calculatorThese are related but not identical concepts.
Comparison with C++
| Go | C++ |
|---|---|
| Package | Namespace |
calculator.Add() | calculator::Add() |
calculator.Book | calculator::Book |
| Uppercase = exported | public |
| Lowercase = package-private | private (roughly equivalent) |
Packages provide organization and namespacing without introducing additional complexity.
Session Summary
Topics covered:
-
Packages
-
Import paths
-
Package names
-
Namespaces
-
Exported identifiers
-
Struct field visibility
-
Multiple files within a package
-
Package aliases
Practical skills gained:
-
Organizing code into packages
-
Importing custom packages
-
Understanding Go’s visibility rules
-
Recognizing packages as namespaces
Key Takeaways
-
Packages organize related code.
-
Every exported identifier is accessed as
Package.Identifier. -
Import paths are based on the module name and directory structure.
-
Uppercase identifiers are exported.
-
Lowercase identifiers are visible only within the same package.
-
A package may consist of multiple source files.
Next Topics
- Error handling
- The
errortype - Multiple return values
defer- Panic vs ordinary errors
- Go Learning - Session 7