Go code is organized into packages.

Packages

Having both these files

greet.go:

package main
 
import "fmt"
 
func greet() {
	fmt.Println("Hello world")
}

and main.go:

package main
 
func main() {
 
	greet()
}

We can simply use the function greetfrom the other file. In order to run our main.go successfully as the entry point in our app, use go run main.go greet.go to show Go which files are relevant. That’s all you need to “import” a function from another file.

Even easier when using

Data visibility

In Go, all variables declared outside of any function are visible at package-level. This means that all these variables can be used in another file of the same package, as if the variable was declared in the same file.

Across packages, only variables outside of functions, starting with a capital letter are exported. Everything starting lowercase is not. Here is an example:

// exported: 
var Name string = "Max"
 
// not exported: 
var age int = 22

You can tell this by using values exported from standard packages in Go. All constants from the math package are written uppercase, and therefore can be used anywhere in your project.

Function visibility

As functions are also variables in Go, keep in mind that the same principle applies to functions too. Only functions with a name starting with a capital letter are exported.

Package management

Go got an inbuilt package manager

Creating packages

A popular scenario is creating another package in your project in a subdirectory.

Important principles:

  • The name of your package should be the name of the subdirectory

Packages in your project can be imported and their variables used like this:

import "<module-name>/<package-name>"
 
func main() {
	<module-name>.<variable> 
}

E. g.

import (
	"fmt"
	"main/util"
)
 
func main() {
	util.UtilStuff()
}

Conventions for creating packages

While having a huge Go project across multiple files all using one package is technically no problem, it isn’t recommended. Usually, one project holds multiple packages, that are split into functionalities like database, networking, business logic etc.

Naming:

  • Use lowercase, single-word names for your packages. Avoid underscores or mixed case. This improves readability and keeps things concise.
  • The package name should ideally match the base name of the directory containing the Go source files. For example, a package named math would reside in a directory called math.

Structure:

  • Organize packages by functionality. Group related code together to create a logical and maintainable codebase.
  • Maintain consistency in your naming conventions and directory structure throughout your project. This makes the code easier to navigate and understand for everyone involved.

General Practices:

  • Clearly define which elements of your package are exported (accessible from other programs) and which are internal (used only within the package).
  • Avoid overly broad names like “common” or “util” for your packages. Strive for descriptive names that reflect the specific functionality provided.
  • If you’re creating a public package, consider using a vendor prefix like yourcompany.com/ to avoid naming conflicts with standard library packages or other projects.

Next chapter: Interfaces