Golang

Installation

Install Go:

1GO_VERSION="1.21.0"
2
3wget https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz
4sudo rm -rf /usr/local/go
5sudo tar -C /usr/local -xzf go${GO_VERSION}.linux-amd64.tar.gz
6
7export PATH="/usr/local/go/bin:$PATH"
8
9go version

To keep Go available after reboot:

1echo 'export PATH="/usr/local/go/bin:$PATH"' >> ~/.bashrc
2source ~/.bashrc

Create a project

1mkdir myapp
2cd myapp
3
4go mod init myapp

A go.mod file is created:

1myapp/
2└── go.mod

It describes the Go module and its dependencies.

Hello World

Create main.go:

1package main
2
3import "fmt"
4
5func main() {
6    fmt.Println("Hello World")
7}
1go run .
2go build

This creates a binary: ./myapp

Variables

 1package main
 2
 3import "fmt"
 4
 5func main() {
 6    name := "Gopher"
 7    age := 10
 8
 9    fmt.Println(name, age)
10}

Variables can also be declared explicitly:

1var name string = "Gopher"
2var age int = 10

The short syntax is commonly used inside functions:

1name := "Gopher"

Functions

Functions are declared with func:

1func hello(name string) string {
2    return "Hello " + name
3}

Use it:

1func main() {
2    message := hello("Gopher")
3    fmt.Println(message)
4}

A function can return several values:

1func divide(a, b int) (int, error) {
2    if b == 0 {
3        return 0, fmt.Errorf("division by zero")
4    }
5
6    return a / b, nil
7}

Conditions

1if age >= 18 {
2    fmt.Println("adult")
3} else {
4    fmt.Println("minor")
5}

Go does not require parentheses around conditions.

Loops

Go uses for for loops:

1for i := 0; i < 5; i++ {
2    fmt.Println(i)
3}

It can also behave like a while loop:

1i := 0
2
3for i < 5 {
4    fmt.Println(i)
5    i++
6}

Slices

Slices are commonly used instead of arrays:

1names := []string{
2    "Alice",
3    "Bob",
4    "Charlie",
5}
6
7for _, name := range names {
8    fmt.Println(name)
9}

Add an element:

1names = append(names, "Dave")

Maps

Maps store key/value pairs:

1ports := map[string]int{
2    "http":  80,
3    "https": 443,
4}
5
6fmt.Println(ports["https"])

Loop over a map:

1for name, port := range ports {
2    fmt.Println(name, port)
3}

Structs

Structs group related data:

1type Server struct {
2    Name string
3    Port int
4}

Create one:

1server := Server{
2    Name: "web",
3    Port: 8080,
4}
5
6fmt.Println(server.Name)

Methods

Methods are functions attached to a type:

1type Server struct {
2    Name string
3}
4
5func (s Server) Start() {
6    fmt.Println("Starting", s.Name)
7}

Usage:

1server := Server{Name: "web"}
2server.Start()

Error handling

Go usually returns errors explicitly:

1file, err := os.Open("config.yaml")
2if err != nil {
3    return err
4}
5
6defer file.Close()

A very common pattern is:

1result, err := doSomething()
2if err != nil {
3    return err
4}

Go does not use exceptions for normal error handling.

Packages

Code can be split into packages.

Example:

1myapp/
2├── main.go
3└── greeting/
4    └── greeting.go

greeting/greeting.go:

1package greeting
2
3func Hello(name string) string {
4    return "Hello " + name
5}

Use it from main.go:

 1package main
 2
 3import (
 4    "fmt"
 5
 6    "myapp/greeting"
 7)
 8
 9func main() {
10    fmt.Println(greeting.Hello("Gopher"))
11}

Names beginning with an uppercase letter are exported:

1func Hello() {}

Names beginning with lowercase are private to the package:

1func hello() {}

Common structure

A small application can simply use:

1myapp/
2├── go.mod
3├── go.sum
4└── main.go

As the project grows, a common structure is:

 1myapp/
 2├── cmd/
 3│   └── myapp/
 4│       └── main.go
 5│
 6├── internal/
 7│   ├── app/
 8│   ├── config/
 9│   └── service/
10│
11├── go.mod
12└── go.sum

Typical responsibilities:

 1cmd/
 2    application entry points
 3
 4internal/
 5    private application packages
 6
 7go.mod
 8    module and dependency definition
 9
10go.sum
11    dependency checksums

main.go should generally stay small:

1package main
2
3import "myapp/internal/app"
4
5func main() {
6    app.Run()
7}

The application logic can then live under internal/.

Useful commands

1go run .
2go build
3go test ./...
4go fmt ./...
5go vet ./... #Static analysis:
6go mod download
7go mod tidy
8go install .

Basic workflow

A typical Go workflow is:

 1create module
 2    ↓
 3write packages
 4    ↓
 5go fmt
 6    ↓
 7go test
 8    ↓
 9go vet
10    ↓
11go build

The main ideas to remember are:

1package     groups Go code
2func        defines behavior
3struct      groups data
4interface   describes behavior
5error       represents failures
6go.mod      defines the module

Sources

Saturday, October 3, 2026 Thursday, January 1, 2026