Summary: in this tutorial, you’ll learn about Go packages to organize code and make it reusable.
Introduction to Go packages
In Go, a package is a collection of related source code files that are compiled together. Each package serves a single purpose.
Packages in Go are similar to modules or libraries in other programming languages.
Every standalone Go program has at least one package called main
:
package main
import "fmt"
var message = "Hello, World!"
func say(message string) {
fmt.Println(message)
}
func main() {
say(message)
}
Code language: Go (go)
When you launch the program, Go runtime looks for the main()
function inside the main
package. Therefore, a Go program requires at least a main
package that includes the main()
function.
Package scopes
In the above program, the main
package includes a message
variable, the say
and main
functions. These variables and functions are package scope.
In Go, identifiers such as variables and functions are either package or function scope. There is no “global” scope.
In Go, you can declare anything at package scope. But you can’t use the short declaration operator :=
. For example, the following declaration results in a compilation error:
package main
import "fmt"
message := "Hello, World!" // ERROR
// ...
Code language: Go (go)
Package visibility
In Go, any capitalized name is automatically exported. This means that you can use it from other packages.
For example, the Println
function from the fmt
package has the letter P
in uppercase, so you can use it in your package.
On the other hand, any name that is not capitalized can be used only within the package.
Importing packages
A package can import other necessary packages. Like variables, unused package imports will result in an error. To import a package, you use the import
statement followed by the package name:
package name
Code language: Go (go)
To import multiple packages, you place them within parentheses:
import (
"fmt"
"os"
)
Code language: Go (go)
Go does not allow import cycles. For example, a package P
cannot import a package that imports P
. The following will result in an error:
Package p
package p
import "q"
// ...
Code language: Go (go)
Package q:
package q
import "p"
// ...
Code language: Go (go)
To fix this import cycle, you need to move dependencies to a third package or eliminate them.
Package init() function
The init()
function is a special function that the Go runtime will call automatically when the package is initialized.
Typically, you use the init()
function to set up the initial state for the package before any other code within the package executes.
Here are some key points of the init()
function:
- The
init()
function takes no argument and doesn’t return any values. - Each package can have multiple
init()
functions. Go runtime will call them in the order they appear in the package. - Go runtime calls the
init()
function before themain()
function in themain
package. - Typically, you use the
init()
function to initialize package-scoped variables, load the configuration files and establish a database connection.
The following example shows how to use the init()
function to create a log file with the name app.log
and set the log output to that file:
package main
import (
"log"
"os"
)
func init() {
// Create a log file
file, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
log.Fatalf("Failed to open log file: %v", err)
}
// Set log output to the file
log.SetOutput(file)
}
func main() {
log.Println("This is a log message")
}
Code language: Go (go)
Go package example
Step 1. Open your terminal and create a new directory to store the source code files:
mkdir myapp
Code language: Go (go)
Step 2. Navigate to the project directory:
cd myapp
Code language: Go (go)
Step 3. Initialize a Go module:
go mod init myapp
Code language: Go (go)
Step 4. Create a new directory for the greeting package:
mkdir greeting
Code language: Go (go)
Step 5. Create a greeting.go
file inside the greeting package:
package greeting
import (
"fmt"
"time"
)
func Greet(name string) string {
t := time.Now().Hour()
var message string
switch {
case t < 12:
message = fmt.Sprintf("Good morning, %s", name)
case t < 17:
message = fmt.Sprintf("Good afternoon, %s", name)
default:
message = fmt.Sprintf("Good evening, %s", name)
}
return message
}
Code language: Go (go)
The greeting
package has the Greet()
function that returns a greeting message to the person with the specified name.
Step 6. Call the Greet()
function from the greeting
package from the main()
function of the main
package:
package main
import (
"fmt"
"myapp/greeting"
)
func main() {
message := greeting.Greet("Joe")
fmt.Println(message)
}
Code language: Go (go)
How it works.
First, import the fmt
and greeting
packages:
import (
"fmt"
"myapp/greeting"
)
Code language: Go (go)
Second, call the Greet()
method of the greeting package inside the main()
function
func main() {
message := greeting.Greet("Joe")
fmt.Println(message)
}
Code language: Go (go)
Summary
- A package is a collection of related source code files compiled together.
- Go runtime calls
init()
functions in the package first to set the initial state for the package. - Go automatically exports names that are capitalized, so you can use them in other packages.