DEV Community

Andi
Andi

Posted on

Go (Golang) Basic - Structuring Project with Packages

From a Single File to a Real Project

Welcome to the final part of our "Complete Guide to Go Basics" series! So far, all of our code has lived in a single file: main.go. This is fine for small programs, but as your projects grow, you'll need a way to organize your code into logical, reusable pieces.

In Go, the solution is Packages.

Analogy: Think of packages like folders on your computer. You don't put all your documents, photos, and music into one giant folder. You organize them into separate, dedicated folders. Packages do the same for your code.

1. What is a Package?

A package is simply a directory or folder containing one or more Go files that all belong together. Every Go file must declare which package it belongs to at the very top of the file (e.g., package main).

Let's create our own package. Imagine we want to build a simple calculator utility.

Step 1: Create the Package Directory

Inside your project folder (e.g., my-go-project), create a new sub-folder named calculator.

Your project structure should now look like this:

my-go-project/
├── go.mod
├── main.go
└── calculator/  \<-- Our new package folder

Enter fullscreen mode Exit fullscreen mode

Step 2: Create a File in the Package

Inside the calculator folder, create a new file named add.go.

Step 3: Write the Package Code

Open calculator/add.go and add the following code. Notice the first line!

// This file belongs to the 'calculator' package
package calculator

// Add is a function that takes two integers and returns their sum.
// We'll discuss why 'A' is capitalized in a moment.
func Add(a int, b int) int {
    return a + b
}
Enter fullscreen mode Exit fullscreen mode

Key Rule: All .go files inside the calculator directory must start with package calculator.

2. Importing and Using Your Package

Now that we have our calculator package, how do we use the Add function from our main.go file? We use the import keyword.

Open your main.go file and modify it to look like this:

package main

import (
    "fmt"
    "my-first-go-project/calculator" // Import our custom package
)

func main() {
    // Call the Add function from the calculator package
    sum := calculator.Add(5, 3)

    fmt.Println("The sum is:", sum) // Prints: The sum is: 8
}
Enter fullscreen mode Exit fullscreen mode

How it works:

  • We import our package using its full path: <module_name>/<package_name>. The module name is the one you defined in your go.mod file.
  • To use the function, we prefix it with the package name: calculator.Add().

3. Go's Simple Visibility Rule: The Capital Letter

You might have noticed that we named our function Add with a capital A. This was intentional and is one of the most elegant features of Go.

In Go, there is no public or private keyword. Visibility is determined by a simple rule:

  • If a name (function, struct, variable, etc.) starts with a capital letter, it is Public (Exported). This means it can be accessed from other packages.
  • If a name starts with a lowercase letter, it is Private (unexported). This means it can only be accessed by code within the same package.

Analogy: A restaurant.

  • Public (Capital Letter): The Menu given to customers. Anyone can see it and order from it.
  • Private (lowercase letter): The secret recipe in the kitchen. Only the chefs (code in the same package) can access it.

Let's prove this. Add a new subtract function with a lowercase 's' to your calculator/add.go file:

// in calculator/add.go

package calculator

func Add(a int, b int) int {
    return a + b
}

// 's' is lowercase, so this function is private
func subtract(a int, b int) int {
    return a - b
}
Enter fullscreen mode Exit fullscreen mode

Now, try to call subtract from main.go:

// in main.go
package main

import (
    "fmt"
    "my-first-go-project/calculator"
)

func main() {
    sum := calculator.Add(5, 3)
    fmt.Println("The sum is:", sum)

    // This line will cause a compilation error!
    // diff := calculator.subtract(5, 3) 
}
Enter fullscreen mode Exit fullscreen mode

If you try to run this, Go will give you an error saying cannot refer to unexported name calculator.subtract. This is Go's way of protecting your private code.

Conclusion: You've Built a Strong Foundation!

Congratulations! You have officially reached the end of our "Complete Guide to Go Basics" series. You've journeyed from a simple "Hello, World!" to understanding some of Go's most powerful and unique features.

Let's recap what you've mastered:

  • The Basics: Variables, data types, and collections like slices and maps.
  • Control Flow: Making decisions with if/switch and repeating tasks with for.
  • Code Structure: Organizing logic into functions, creating custom types with structs, and attaching behavior with methods.
  • Advanced Concepts: Using pointers for efficiency, handling errors gracefully, and now, structuring your project with packages.

You now have a very solid foundation. The Go world is vast, and your next steps could be exploring:

  • Goroutines and Channels: Go's famous approach to concurrency.
  • The Standard Library: Discovering Go's rich set of built-in packages.
  • Building a Project: Creating your first web API or command-line tool.

Thank you for following along with this series. I hope it has been a helpful and enjoyable journey. Happy coding!

Top comments (0)