A Go package is a group of Go source code files that are compiled together and are located in the same directory. These packages are typically used to export and import code between them. As a result, the code is now modular and simple to maintain. However, learning how to import local packages in Go might be really challenging if you are just starting out. This tutorial focuses on it.
Introduction to Golang package
A package is only a directory inside your Go workspace that contains one or more Go source files or other Go packages. Every Go source file must belong to a package. The following syntax is used to declare a source file as a component of a package:
package <packagename>
The benefits of package management:
- Reducing conflicts: The names of functions might be the same across many packages. This maintains the names of our functions short and brief.
- Making your program organized: It groups together pieces of code that are related to make it simpler to locate the code you want to reuse.
- Boosting up your performance: just the smaller, modified portions of the program need to be recompiled. We don't have to recompile theÂ
fmt
 package every time change our program.
Golang main function and main package
main function: The entry point for the application is the main function in the main package as described in the specification:
A complete program is created by linking a single, unimported package called the main package with all the packages it imports, transitively. The main package must have package nameÂ
main
 and declare a functionÂmain
that takes no arguments and returns no value. Program execution begins by initializing the main package and then invoking the functionÂmain
. When that function invocation returns, the program exits. It does not wait for other (non-main) goroutines to complete.
func main() { … }
Noted that when you build shared libraries, you will not have any main package and main function in the package.
Creating and Reusing Local Packages
Create and write some local packages
Take a look at the workspace project as an example to help you better understand what a go package is. There are two folders named: pack1 and pack2 inside the workspace directory. We also create a sub-folder inside pack1. To create folders, run the following command on Linux:
mkdir pack1 // for files in pack1 mkdir pack1/subpack1 mkdir pack2 // for files in pack2
For example, let us create go source files for the pack1, pack2, and the main file:
touch pack1/helper1.go touch pack1/subpack1/sub_helper1.go touch pack2/helper2.go touch ./main.go
Here is the folder architecture:
Let's now add some code to helper1.go and help2.go and sub_helper1.go. Noted that at the first line of each file, include the package namespace as:
package pack1
 helper1.go:
package pack1
import "fmt"
func SayHello() {
fmt.Println("Hello everyone from package1")
}
sub_helper1.go
package subpack1
import "fmt"
func SayCustomHello() {
fmt.Println("Hello everyone from sub_package1. This is custom message from GoLinuxCloud!")
}
help2.go
package pack2
import "fmt"
func sayGoodBye() {
fmt.Println("Goodbye everyone from package2")
}
The above functions from packages are simple. They are just functions that print out some messages.
Golang Import Local Packages
The last step is to import your local packages so you can use the code in each one of them. In the main package, create a main.go
file. Next, add the following lines to import your local packages:
package main
import (
"workspace/pack1"
"workspace/pack1/subpack1"
"workspace/pack2"
)
func main() {
pack1.SayHello()
subpack1.SayCustomHello()
pack2.sayGoodBye()
}
Output:
# command-line-arguments
.\main.go:11:2: undefined: pack2
This will be an error because pack2.sayGoodBye()
is unreported.
An identifier may be exported to permit access to it from another package. An identifier is exported if both:
- the first character of the identifier's name is a Unicode uppercase letter (Unicode character category Lu); and
- the identifier is declared in the package block or it is a field name or method name.
package main
import (
"workspace/pack1"
"workspace/pack1/subpack1"
)
func main() {
pack1.SayHello()
subpack1.SayCustomHello()
// pack2.sayGoodBye()
}
Output:
Hello everyone from package1
Hello everyone from sub_package1. This is custom message from GoLinuxCloud!
Noted that your workspace must be located inside the GOROOT or GOPATH folder or else this error will prompt:
C:\Program Files\Go\src\workspace\pack1\subpack1 (from $GOROOT) C:\Users\nguye\go\src\workspace\pack1\subpack1 (from $GOPATH)
Summary
In this article, we discussed how you can export and import code using Go packages. Go's design philosophy is to create reusable code blocks called packages, and then use these packages to create your application. Package directories are used to organize Go programs. By building individual Go packages into an application, Go enables you to execute software composition. Go packages improve maintainability, modularity, and code reuse. After reading this article, we hope you can import the local packages to your project.
References
https://go.dev/ref/spec#Program_execution
https://go.dev/ref/spec#Exported_identifiers