Published on
· July 10, 2026

Golang: what it is, what it is for, and how to get started in the language

Blog
  • Photo of Henrico Piubello
    Henrico Piubello
    Henrico Piubello
    IT Specialist - Grupo Voitto

    IT Specialist - Grupo Voitto

Go, also known as Golang, is an open-source programming language created at Google and announced in November 2009. Compiled, with static typing and lean syntax, it was designed to build servers, cloud tools, and large-scale distributed systems with native concurrency.

Logo and gopher mascot of the Go (Golang) programming language in illustrative art

What is Go (Golang)?

Go is a compiled, open-source programming language, developed by Robert Griesemer, Rob Pike, and Ken Thompson at Google. The project was publicly announced in November 2009 and reached version 1.0 in March 2012, with the compatibility promise it maintains to this day.

The main motivation behind Go's creation was to address the perceived gaps in other languages within large-scale development environments, like Google's own: slow compilation, complex dependencies, and the difficulty of writing safe concurrent code.

Adoption proves the proposal. According to the Stack Overflow Developer Survey 2025, 13.5% of developers use Go, and the Go Developer Survey 2025, conducted by the language's team with 5,379 respondents, recorded 91% satisfaction among those who program in Go. In the TIOBE index, the language reached the 7th position in 2025, its best historical mark — which puts it in direct dispute with the most used programming languages in the world.

Projects like Docker and Kubernetes, pillars of modern cloud infrastructure, were written in Go — a good indicator of where the language shines: APIs (Application Programming Interfaces), microservices, and system tools.

What are the main characteristics of Go?

Go stands out for three pillars: syntax simplicity, fast compilation to native binaries, and concurrency built into the language. The table below summarizes what each characteristic delivers in practice.

CharacteristicHow it worksPractical benefit
Native compilationGenerates a single, self-sufficient binarySimple deploy and fast startup
Static typingTypes checked at compile timeFewer errors reach production
GoroutinesLightweight threads managed by the runtimeThousands of simultaneous tasks
ChannelsSynchronized communication between goroutinesConcurrency without manual locks
Garbage collectorFrees memory automaticallyFewer memory leaks
Built-in toolsgofmt, go test, and go vet in the toolchainStandardization without extra config

In summary:

  • Simplicity and clarity: Go values a clean and direct syntax, with few keywords, which makes code easier to read and write in large teams.
  • Execution efficiency: Go is optimized for performance, offering fast compilation and efficient execution, an effective choice for high-performance systems.
  • Concurrency made simple: Go simplifies concurrency with goroutines and channels, allowing you to handle concurrent processes intuitively.

Variables in Go: declaration and type inference

In Go, variable declaration uses the var keyword followed by the variable name and type. The language also offers type inference with the := operator, allowing the compiler to deduce the type automatically from the assigned value.

package main

import "fmt"

func main() {
    // Declaring variables with explicit types
    var numeroInteiro int
    var numeroReal float64
    var texto string
    var condicao bool

    // Assigning values to variables
    numeroInteiro = 42
    numeroReal = 3.14
    texto = "Olá, Go!"
    condicao = true

    // Declaring variables with type inference
    nome := "Alice"
    idade := 25

    // Printing the values
    fmt.Println(numeroInteiro, numeroReal, texto, condicao)
    fmt.Println("Nome:", nome, "Idade:", idade)
}

An important particularity: variables declared and not used generate a compilation error in Go. This intentional strictness keeps the code lean and eliminates "leftovers" that accumulate in large projects.

Control structures in Go: if, switch, and for

Go offers a reduced and direct set of control structures: if/else for conditionals, switch for multiple conditions, and a single loop, for, which covers all repetition cases.

Conditionals (if, else, switch)

Go's if structure dispenses with parentheses in the condition, and the else block is optional. switch offers a cleaner alternative for several conditions — and, unlike other languages, does not require break in each case.

package main

import "fmt"

func main() {
    x := 10

    // if-else structure
    if x > 5 {
        fmt.Println("x é maior que 5")
    } else {
        fmt.Println("x é menor ou igual a 5")
    }

    // switch structure
    switch x {
    case 5:
        fmt.Println("x é igual a 5")
    case 10:
        fmt.Println("x é igual a 10")
    default:
        fmt.Println("x não é nem 5 nem 10")
    }
}

Loops (for)

The for loop in Go is versatile: it covers the traditional counter loop, the "while" style, and iteration over collections using the range keyword.

package main

import "fmt"

func main() {
    // Basic loop
    for i := 0; i < 5; i++ {
        fmt.Println(i)
    }

    // Loop using range (iterating over a collection)
    nomes := []string{"Alice", "Bob", "Charlie"}
    for indice, nome := range nomes {
        fmt.Printf("%d: %s\n", indice, nome)
    }
}

Functions in Go: parameters and multiple returns

Go supports functions with typed parameters and return values, including multiple values in a single function — a pattern widely used to return result and error together. Named returns make code easier to understand.

package main

import "fmt"

// Simple function that returns the sum of two numbers
func somar(a, b int) int {
    return a + b
}

// Function that returns multiple values
func dividir(dividendo, divisor int) (quociente, resto int) {
    quociente = dividendo / divisor
    resto = dividendo % divisor
    return
}

func main() {
    // Calling functions
    resultadoSoma := somar(3, 4)
    fmt.Println("Soma:", resultadoSoma)

    quociente, resto := dividir(10, 3)
    fmt.Printf("Quociente: %d, Resto: %d\n", quociente, resto)
}

What types and data structures does Go offer?

Go offers basic types (integers, floating point, booleans, and strings) and three main collection structures: fixed-size arrays, dynamic slices, and key-value maps. Those who have already studied data structures in programming will recognize the concepts with a more direct syntax.

Basic types (integers, floating point, booleans)

package main

import "fmt"

func main() {
    // Integer types
    var idade int = 25
    var numeroNegativo int = -5

    // Floating point types
    var altura float64 = 1.75
    var pi float64 = 3.14159

    // Boolean types
    var verdadeiro bool = true
    var falso bool = false

    // Printing the values
    fmt.Println("Idade:", idade)
    fmt.Println("Número Negativo:", numeroNegativo)
    fmt.Println("Altura:", altura)
    fmt.Println("Pi:", pi)
    fmt.Println("Verdadeiro:", verdadeiro)
    fmt.Println("Falso:", falso)
}

Collection structures (arrays, slices, maps)

package main

import "fmt"

func main() {
    // Arrays (fixed)
    var numeros [3]int
    numeros[0] = 1
    numeros[1] = 2
    numeros[2] = 3

    // Slices (dynamic)
    frutas := []string{"Maçã", "Banana", "Morango"}

    // Maps (key-value)
    capitais := map[string]string{
        "Brasil": "Brasília",
        "EUA":    "Washington D.C.",
        "Japão":  "Tóquio",
    }

    // Printing the values
    fmt.Println("Array de Números:", numeros)
    fmt.Println("Slice de Frutas:", frutas)
    fmt.Println("Mapa de Capitais:", capitais)
}

In practice, slices are the most used structure in day-to-day Go: they grow dynamically over an underlying array and are the default type for lists of data.

How does concurrency work in Go?

Concurrency in Go works through goroutines — functions that execute independently over lightweight threads managed by the runtime — and channels, which synchronize and exchange data between them. Rob Pike, one of the language's creators, summed up the model in the talk "Concurrency is not parallelism": concurrency is structuring the program into independent tasks; parallelism is executing them at the same time.

Goroutines

Goroutines are lightweight threads managed by the Go runtime, much cheaper than operating system threads. A goroutine is started simply by prefixing the function call with the go keyword.

package main

import (
    "fmt"
    "time"
)

func imprimirNumeros() {
    for i := 1; i <= 5; i++ {
        time.Sleep(500 * time.Millisecond)
        fmt.Println("Goroutine -", i)
    }
}

func main() {
    // Starting a goroutine
    go imprimirNumeros()

    // Execution on the main thread
    for i := 1; i <= 5; i++ {
        time.Sleep(250 * time.Millisecond)
        fmt.Println("Main -", i)
    }
}

Channels

Channels are used for communication between goroutines. They facilitate synchronization and data exchange without manual locks: the <- operator sends data to a channel (canal <- valor) and also receives data from it (valor := <-canal).

package main

import (
    "fmt"
    "time"
)

func enviarDados(canal chan string) {
    for i := 1; i <= 3; i++ {
        canal <- fmt.Sprintf("Dado %d", i)
        time.Sleep(500 * time.Millisecond)
    }
    close(canal)
}

func main() {
    // Creating a channel
    canal := make(chan string)

    // Starting a goroutine to send data through the channel
    go enviarDados(canal)

    // Receiving data from the channel
    for mensagem := range canal {
        fmt.Println("Recebido:", mensagem)
    }
}

Select statements

select is used to handle multiple communication operations at the same time. It allows the program to wait on multiple channels, executing the case of the first one that is ready.

package main

import (
    "fmt"
    "time"
)

func main() {
    canal1 := make(chan string)
    canal2 := make(chan string)

    // Goroutine 1
    go func() {
        for {
            canal1 <- "Canal 1"
            time.Sleep(2 * time.Second)
        }
    }()

    // Goroutine 2
    go func() {
        for {
            canal2 <- "Canal 2"
            time.Sleep(3 * time.Second)
        }
    }()

    // Select statement to receive from multiple channels
    for i := 0; i < 5; i++ {
        select {
        case mensagemCanal1 := <-canal1:
            fmt.Println("Recebido do Canal 1:", mensagemCanal1)
        case mensagemCanal2 := <-canal2:
            fmt.Println("Recebido do Canal 2:", mensagemCanal2)
        }
    }
}

How to manage packages and dependencies with Go Modules?

Go organizes code into packages and manages dependencies with Go Modules, the official system introduced in Go 1.11 and standard since Go 1.16. It records exact versions in go.mod and go.sum, ensuring reproducible builds.

Code organization in packages

Packages are sets of files that work together to provide a specific functionality. They facilitate code modularity, reuse, and maintenance.

package util

import "fmt"

// FuncaoUtil is a function of the util package
func FuncaoUtil() {
    fmt.Println("Executando FuncaoUtil")
}

Importing external packages

To use external features, the import statement references packages by repository path. In the example below, we import Gin, a popular web framework in the Go ecosystem.

package main

import (
    "net/http"

    "github.com/gin-gonic/gin"
)

func main() {
    router := gin.Default()
    router.GET("/", func(c *gin.Context) {
        c.String(http.StatusOK, "Olá, mundo!")
    })
    router.Run(":8080")
}

Starting a module

To start a Go module, run go mod init module-name in the project directory. The go.mod file will be generated to track dependencies.

// go.mod file
module nomedoexemplo

go 1.22

Then, use go get to add dependencies:

go get exemplo.com/pacote

Go Modules downloads and manages dependencies automatically, recording verification hashes in the go.sum file:

// go.sum file
exemplo.com/pacote v1.2.3 h1:abc123...

The main advantages of Go Modules are explicit versioning (versions pinned in go.mod), the ease of adding, removing, or updating dependencies, and support for private or alternative repositories.

How do interfaces work in Go?

Interfaces in Go specify an object's behavior through a set of methods without implementation. Implementation is implicit: any type that has all the methods of an interface is automatically considered an implementation of it, without the need to declare implements.

package main

import "fmt"

// Defining an interface
type Animal interface {
    Som() string
    Mover() string
}

// Implementing the interface for a specific type (Cachorro)
type Cachorro struct{}

func (c Cachorro) Som() string {
    return "Au au!"
}

func (c Cachorro) Mover() string {
    return "Correndo"
}

// Function that accepts any type implementing the Animal interface
func DescreverAnimal(a Animal) {
    fmt.Println("Som:", a.Som())
    fmt.Println("Movimento:", a.Mover())
}

func main() {
    // Creating an instance of Cachorro
    meuCachorro := Cachorro{}

    // Calling the function with the Cachorro instance
    DescreverAnimal(meuCachorro)
}

In this example, the Animal interface defines two methods, Som and Mover. The Cachorro type implements these methods and, thereby, implicitly becomes an implementation of the Animal interface.

The benefits are direct: interfaces enable polymorphism (different types behaving similarly) and abstraction (code depends on behavior, not concrete implementation), which facilitates the extensibility of Go programs.

Where to learn Go and join the community?

The best starting points for learning Go are the official and free resources maintained by the language's own team, complemented by an active community in forums and networks.

  • Official Go documentation: the primary source for understanding the language's fundamentals, standard packages, and best practices.
  • A Tour of Go: an interactive tour that walks through the basic concepts of the language right in the browser.
  • Go by Example: practical, commented examples of how to use Go in common tasks.

To consolidate learning, solving real exercises accelerates things a lot — see this selection of sites with programming challenges. And if you are deciding between backend languages, the Java vs. Go comparison here on CodeCrush details the differences in performance, ecosystem, and market between the two.

Conclusion

Go delivers a rare combination: the simplicity of a language that is learned in weeks with the performance and concurrency demanded by production systems at scale. It is no coincidence that Docker, Kubernetes, and much of the modern cloud infrastructure were written in Go — nor that 91% of the developers who use it declare themselves satisfied. If your goal is backend, DevOps, or distributed systems, learning Go in 2026 is one of the safest bets you can make for your career.

## faq

Frequently asked questions

What is the Go language for?

Go is mainly used for backend development: APIs, microservices, command-line tools, and cloud infrastructure. Tools like Docker and Kubernetes were written in Go. The language compiles to native binaries and handles thousands of simultaneous connections well, which makes it common in high-demand distributed systems.

Are Go and Golang the same thing?

Yes. The official name of the language is Go, but the term Golang arose because of the original domain golang.org and makes internet searches easier, since the word go is too generic to search for. Official documentation, the community, and job postings use both names for the same language.

Is it worth learning Go in 2026?

Yes, especially for those who want to work with backend and infrastructure. According to the Stack Overflow Developer Survey 2025, 13.5% of developers use Go, and the Go Developer Survey 2025 recorded 91% satisfaction. The cloud, DevOps, and microservices market demands the language, and the simple syntax shortens the learning curve.

Is Go compiled or interpreted?

Go is a compiled language: the source code is transformed directly into a native binary, without depending on a virtual machine or interpreter. This generates self-sufficient executables, easy to distribute in containers, with fast startup and good performance, while keeping features like automatic garbage collection.

What are goroutines in Go?

Goroutines are functions executed concurrently, managed by the Go runtime instead of the operating system. They are much lighter than traditional threads, allowing you to create thousands of them in a single program. Communication between goroutines happens through channels, which synchronize and exchange data safely.

Topics in this article

## continue lendo

Keep browsing

About the author

Photo of Henrico Piubello

Henrico Piubello

IT Specialist - Grupo Voitto · Grupo Voitto

See profile and all articles