Demystifying Go (Golang), Google's Programming Language: Packages
Vagner Nascimento
Software Engineer | Go (golang) | NodeJS (Javascrit) | AWS | Azure | CI/CD | Git | Devops | Terraform | IaC | Microservices | Solutions Architect
Introduction
Packages are Go’s way of helping us modularize our code and share functionalities across different parts of an application. With them, we build a well-structured program where each module has its own responsibility, but they all work together to form the final product. So far, we've only worked with the main package, running a single file. In this chapter, we’ll explore how to create and use new packages. Come along, Gopher! Let’s dive into this journey together.
Visibility and Packages
Before we get started, we need to cover some essential concepts about packages in Go. In Go, simplicity is key: there are only two options for visibility—public and private. That’s right, there’s no protected or internal like in other languages. If a function, variable, or type starts with an uppercase letter, it’s public (accessible outside the package). If it starts with a lowercase letter, it’s private (accessible only within the package).
Another important characteristic is that this visibility applies only between packages, not between files. Within a package, you can have as many files as you like, but they all share the same “visibility space.” This means we can’t have two items with the same name in different files within the same package.
Each package should be in its own directory, and by convention, the directory and package names should match. If we try to define more than one package in the same directory, Go will complain (and won’t compile). Check out the example below, where we try to create the calc package in the same folder as main:
Tip: The command go run *.go executes all .go files in the folder, including subfolders.
Now, see how everything works correctly when we move the calc package file into its own folder:
Go’s simplicity is also reflected in how it handles visibility: there are no extra keywords; it’s all about the uppercase or lowercase starting letter to indicate whether something is public or private.
Creating a Module and Packages
To organize our application, we first create a module with go mod init module_name. This command creates the go.mod file, which stores information about the module. With a configured module, we can add internal packages and import external ones (for example, a package to work with SQL). See below how we create a module called article:
Now, let’s use the calc package we created. Note that the Point type and its attributes must start with uppercase letters to be accessible by the main package:
In the calc package, we create the necessary structure to calculate the distance between two points. First, we define the Point type, which contains the X and Y coordinates. Then, we add a private function, catheters, that calculates the differences between coordinates. This function is only visible within calc. Check out the example below:
Next, we create the public Distance function in the calc package. It takes two points, calculates the distance between them using catheters, and returns the result. This public function can be used in main:
External Packages
In Go, creating packages and publishing them on repositories like GitHub makes it easy to reuse code across multiple projects. In the example below, I created the gostudiesarea package as a demonstration. This package contains functions for calculating the circumference of a circle and the area of a rectangle:
To import an external package, we use the command go get github.com/vagner-nascimento/gostudiesarea. The format is git_name.com/developer-name/project_name, and by convention, project_name should match the package name. After running this command, Go updates go.mod and creates go.sum, which lists all external dependencies for the project:
Now we can call the package in main and use its functions:
Conclusion
Packages are the foundation for structuring applications in Go, allowing for clean and reusable code organization. Go’s simplicity is a strength here: only two visibility options, straightforward naming conventions to indicate public or private access, and a module system that makes it easy to import external packages or create internal ones. By modularizing our code, we create an organized and maintainable application.
Following this approach not only improves readability and maintainability but also makes our code more collaborative and scalable. So next time you’re writing a new feature, think about how it could be modularized into a package—after all, who doesn’t love well-organized code?
Senior Fullstack Engineer | Typescript Developer | Nodejs | Reactjs | Typescript | AWS | Rust
1 周Amazing
Blockchain Developer @ Itaú Digital Assets | Go | Blockchain | Aws
1 周Great content!
Senior Software Engineer | Fullstack Developer | .NET & C# | Angular & Javascript | Azure | SQL Server
2 周Great perspective! I learned a lot from this.
Senior Fullstack Engineer | Front-End focused developer | React | Next.js | TypeScript | Node | Azure | GCP | SQL | MongoDB
2 周Very nice
Data Engineer | AWS | GCP | Python | SQL
2 周Interesting, thanks for sharing! ??