Publicado em
·

Golang: o que é, para que serve e como começar na linguagem

Autores

Go, também conhecida como Golang, é uma linguagem de programação open source criada no Google e anunciada em novembro de 2009. Compilada, com tipagem estática e sintaxe enxuta, ela foi projetada para construir servidores, ferramentas de nuvem e sistemas distribuídos em larga escala com concorrência nativa.

Logotipo e mascote gopher da linguagem de programação Go (Golang) em arte ilustrativa

O que é Go (Golang)?

Go é uma linguagem de programação compilada e de código aberto, desenvolvida por Robert Griesemer, Rob Pike e Ken Thompson no Google. O projeto foi anunciado publicamente em novembro de 2009 e alcançou a versão 1.0 em março de 2012, com a promessa de compatibilidade que mantém até hoje.

A motivação principal por trás da criação do Go foi resolver as lacunas percebidas em outras linguagens dentro de ambientes de desenvolvimento de grande escala, como os do próprio Google: compilação lenta, dependências complexas e dificuldade de escrever código concorrente seguro.

A adoção comprova a proposta. Segundo o Stack Overflow Developer Survey 2025, 13,5% dos desenvolvedores usam Go, e a Go Developer Survey 2025, conduzida pela equipe da linguagem com 5.379 respondentes, registrou 91% de satisfação entre quem programa em Go. No índice TIOBE, a linguagem atingiu em 2025 a 7ª posição, sua melhor marca histórica — o que a coloca em disputa direta com as linguagens de programação mais usadas do mundo.

Projetos como Docker e Kubernetes, pilares da infraestrutura de nuvem moderna, foram escritos em Go — um bom indicador de onde a linguagem brilha: APIs (Application Programming Interfaces), microsserviços e ferramentas de sistema.

Quais são as características principais do Go?

O Go se destaca por três pilares: simplicidade de sintaxe, compilação rápida para binários nativos e concorrência embutida na linguagem. A tabela abaixo resume o que cada característica entrega na prática.

CaracterísticaComo funcionaBenefício prático
Compilação nativaGera um binário único e autossuficienteDeploy simples e inicialização rápida
Tipagem estáticaTipos verificados em tempo de compilaçãoMenos erros chegam à produção
GoroutinesThreads leves geridas pelo runtimeMilhares de tarefas simultâneas
Canais (channels)Comunicação sincronizada entre goroutinesConcorrência sem locks manuais
Garbage collectorLibera memória automaticamenteMenos vazamentos de memória
Ferramentas embutidasgofmt, go test e go vet no próprio toolchainPadronização sem configuração extra

Em resumo:

  • Simplicidade e clareza: o Go valoriza uma sintaxe limpa e direta, com poucas palavras-chave, que facilita a leitura e a escrita de código em equipes grandes.
  • Eficiência na execução: o Go é otimizado para performance, oferecendo compilação rápida e execução eficiente, uma escolha eficaz para sistemas de alto desempenho.
  • Concorrência de forma simples: o Go simplifica a concorrência com goroutines e canais, permitindo lidar com processos concorrentes de maneira intuitiva.

Variáveis em Go: declaração e inferência de tipo

Em Go, a declaração de variáveis usa a palavra-chave var seguida pelo nome da variável e o tipo. A linguagem também oferece inferência de tipo com o operador :=, permitindo que o compilador deduza o tipo automaticamente a partir do valor atribuído.

package main

import "fmt"

func main() {
    // Declarando variáveis com tipos explícitos
    var numeroInteiro int
    var numeroReal float64
    var texto string
    var condicao bool

    // Atribuindo valores às variáveis
    numeroInteiro = 42
    numeroReal = 3.14
    texto = "Olá, Go!"
    condicao = true

    // Declarando variáveis com inferência de tipo
    nome := "Alice"
    idade := 25

    // Imprimindo os valores
    fmt.Println(numeroInteiro, numeroReal, texto, condicao)
    fmt.Println("Nome:", nome, "Idade:", idade)
}

Uma particularidade importante: variáveis declaradas e não utilizadas geram erro de compilação em Go. Essa rigidez proposital mantém o código enxuto e elimina "sobras" que se acumulam em projetos grandes.

Estruturas de controle em Go: if, switch e for

O Go oferece um conjunto reduzido e direto de estruturas de controle: if/else para condicionais, switch para múltiplas condições e um único loop, o for, que cobre todos os casos de repetição.

Condicionais (if, else, switch)

A estrutura if do Go dispensa parênteses na condição, e o bloco else é opcional. O switch oferece uma alternativa mais limpa para várias condições — e, diferente de outras linguagens, não exige break em cada caso.

package main

import "fmt"

func main() {
    x := 10

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

    // Estrutura switch
    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)

O loop for em Go é versátil: cobre o loop tradicional com contador, o estilo "while" e a iteração sobre coleções usando a palavra-chave range.

package main

import "fmt"

func main() {
    // Loop básico
    for i := 0; i < 5; i++ {
        fmt.Println(i)
    }

    // Loop usando range (iterando sobre uma coleção)
    nomes := []string{"Alice", "Bob", "Charlie"}
    for indice, nome := range nomes {
        fmt.Printf("%d: %s\n", indice, nome)
    }
}

Funções em Go: parâmetros e retornos múltiplos

O Go suporta funções com parâmetros tipados e valores de retorno, inclusive múltiplos valores em uma única função — padrão amplamente usado para retornar resultado e erro juntos. O retorno nomeado facilita a compreensão do código.

package main

import "fmt"

// Função simples que retorna a soma de dois números
func somar(a, b int) int {
    return a + b
}

// Função que retorna múltiplos valores
func dividir(dividendo, divisor int) (quociente, resto int) {
    quociente = dividendo / divisor
    resto = dividendo % divisor
    return
}

func main() {
    // Chamando funções
    resultadoSoma := somar(3, 4)
    fmt.Println("Soma:", resultadoSoma)

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

Quais tipos e estruturas de dados o Go oferece?

O Go oferece tipos básicos (inteiros, ponto flutuante, booleanos e strings) e três estruturas de coleção principais: arrays de tamanho fixo, slices dinâmicos e maps de chave-valor. Quem já estudou estruturas de dados na programação vai reconhecer os conceitos com uma sintaxe mais direta.

Tipos básicos (inteiros, ponto flutuante, booleanos)

package main

import "fmt"

func main() {
    // Tipos inteiros
    var idade int = 25
    var numeroNegativo int = -5

    // Tipos ponto flutuante
    var altura float64 = 1.75
    var pi float64 = 3.14159

    // Tipos booleanos
    var verdadeiro bool = true
    var falso bool = false

    // Imprimindo os valores
    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)
}

Estruturas de coleção (arrays, slices, maps)

package main

import "fmt"

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

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

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

    // Imprimindo os valores
    fmt.Println("Array de Números:", numeros)
    fmt.Println("Slice de Frutas:", frutas)
    fmt.Println("Mapa de Capitais:", capitais)
}

Na prática, slices são a estrutura mais usada no dia a dia em Go: eles crescem dinamicamente sobre um array subjacente e são o tipo padrão para listas de dados.

Como funciona a concorrência em Go?

A concorrência em Go funciona por meio de goroutines — funções que executam de forma independente sobre threads leves gerenciadas pelo runtime — e de canais, que sincronizam e trocam dados entre elas. Rob Pike, um dos criadores da linguagem, resumiu o modelo na palestra "Concurrency is not parallelism" (concorrência não é paralelismo): concorrência é a estruturação do programa em tarefas independentes; paralelismo é executá-las ao mesmo tempo.

Goroutines

Goroutines são threads leves gerenciadas pelo runtime do Go, muito mais baratas que threads do sistema operacional. Uma goroutine é iniciada simplesmente prefixando a chamada de função com a palavra-chave go.

package main

import (
    "fmt"
    "time"
)

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

func main() {
    // Iniciando uma goroutine
    go imprimirNumeros()

    // Execução na thread principal
    for i := 1; i <= 5; i++ {
        time.Sleep(250 * time.Millisecond)
        fmt.Println("Main -", i)
    }
}

Canais (channels)

Canais são usados para a comunicação entre goroutines. Eles facilitam a sincronização e a troca de dados sem locks manuais: o operador <- envia dados para um canal (canal <- valor) e também recebe dados dele (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() {
    // Criando um canal
    canal := make(chan string)

    // Iniciando uma goroutine para enviar dados pelo canal
    go enviarDados(canal)

    // Recebendo dados do canal
    for mensagem := range canal {
        fmt.Println("Recebido:", mensagem)
    }
}

Select statements

O select é usado para lidar com várias operações de comunicação ao mesmo tempo. Ele permite que o programa aguarde múltiplos canais, executando o caso do primeiro que estiver pronto.

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 para receber de múltiplos canais
    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)
        }
    }
}

Como gerenciar pacotes e dependências com Go Modules?

O Go organiza código em pacotes e gerencia dependências com o Go Modules, sistema oficial introduzido no Go 1.11 e padrão desde o Go 1.16. Ele registra versões exatas em go.mod e go.sum, garantindo builds reprodutíveis.

Organização de código em pacotes

Pacotes são conjuntos de arquivos que trabalham juntos para fornecer uma funcionalidade específica. Eles facilitam a modularidade, a reutilização e a manutenção do código.

package util

import "fmt"

// FuncaoUtil é uma função do pacote util
func FuncaoUtil() {
    fmt.Println("Executando FuncaoUtil")
}

Importação de pacotes externos

Para utilizar funcionalidades externas, o comando import referencia pacotes pelo caminho do repositório. No exemplo abaixo, importamos o Gin, um framework web popular no ecossistema Go.

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")
}

Iniciando um módulo

Para iniciar um módulo Go, execute go mod init nome-do-modulo no diretório do projeto. O arquivo go.mod será gerado para rastrear as dependências.

// Arquivo go.mod
module nomedoexemplo

go 1.22

Em seguida, use go get para adicionar dependências:

go get exemplo.com/pacote

O Go Modules baixa e gerencia as dependências automaticamente, registrando os hashes de verificação no arquivo go.sum:

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

As principais vantagens do Go Modules são o versionamento explícito (versões fixadas no go.mod), a facilidade de adicionar, remover ou atualizar dependências e o suporte a repositórios privados ou alternativos.

Como funcionam as interfaces em Go?

Interfaces em Go especificam o comportamento de um objeto por meio de um conjunto de métodos sem implementação. A implementação é implícita: qualquer tipo que possua todos os métodos de uma interface é automaticamente considerado uma implementação dela, sem a necessidade de declarar implements.

package main

import "fmt"

// Definindo uma interface
type Animal interface {
    Som() string
    Mover() string
}

// Implementando a interface para um tipo específico (Cachorro)
type Cachorro struct{}

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

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

// Função que aceita qualquer tipo que implemente a interface Animal
func DescreverAnimal(a Animal) {
    fmt.Println("Som:", a.Som())
    fmt.Println("Movimento:", a.Mover())
}

func main() {
    // Criando uma instância de Cachorro
    meuCachorro := Cachorro{}

    // Chamando a função com a instância de Cachorro
    DescreverAnimal(meuCachorro)
}

Neste exemplo, a interface Animal define dois métodos, Som e Mover. O tipo Cachorro implementa esses métodos e, com isso, torna-se implicitamente uma implementação da interface Animal.

Os benefícios são diretos: interfaces possibilitam polimorfismo (tipos diferentes se comportando de maneira semelhante) e abstração (o código depende do comportamento, não da implementação concreta), o que facilita a extensibilidade de programas Go.

Onde aprender Go e participar da comunidade?

Os melhores pontos de partida para aprender Go são os recursos oficiais e gratuitos mantidos pela própria equipe da linguagem, complementados por uma comunidade ativa em fóruns e redes.

  • Documentação oficial do Go: a fonte primária para entender os fundamentos da linguagem, os pacotes padrão e as melhores práticas.
  • A Tour of Go: um tour interativo que percorre os conceitos básicos da linguagem direto no navegador.
  • Go by Example: exemplos práticos e comentados de como usar Go em tarefas comuns.

Para consolidar o aprendizado, resolver exercícios reais acelera muito — veja esta seleção de sites com desafios de programação. E se você está decidindo entre linguagens de backend, o comparativo Java vs. Go aqui do CodeCrush detalha as diferenças de performance, ecossistema e mercado entre as duas.

Conclusão

O Go entrega uma combinação rara: a simplicidade de uma linguagem que se aprende em semanas com a performance e a concorrência exigidas por sistemas de produção em larga escala. Não é coincidência que Docker, Kubernetes e boa parte da infraestrutura de nuvem moderna tenham sido escritos em Go — nem que 91% dos desenvolvedores que o usam se declarem satisfeitos. Se o seu objetivo é backend, DevOps ou sistemas distribuídos, aprender Go em 2026 é uma das apostas mais seguras que você pode fazer na carreira.

## faq

Perguntas frequentes

Para que serve a linguagem Go?

Go serve principalmente para desenvolvimento backend: APIs, microsserviços, ferramentas de linha de comando e infraestrutura de nuvem. Ferramentas como Docker e Kubernetes foram escritas em Go. A linguagem compila para binários nativos e lida bem com milhares de conexões simultâneas, o que a torna comum em sistemas distribuídos de alta demanda.

Go e Golang são a mesma coisa?

Sim. O nome oficial da linguagem é Go, mas o termo Golang surgiu por causa do domínio original golang.org e facilita buscas na internet, já que a palavra go é genérica demais para pesquisar. Documentação oficial, comunidade e vagas de emprego usam os dois nomes para a mesma linguagem.

Vale a pena aprender Go em 2026?

Vale, principalmente para quem quer trabalhar com backend e infraestrutura. Segundo o Stack Overflow Developer Survey 2025, 13,5% dos desenvolvedores usam Go, e a Go Developer Survey 2025 registrou 91% de satisfação. O mercado de cloud, DevOps e microsserviços demanda a linguagem, e a sintaxe simples encurta a curva de aprendizado.

Go é compilado ou interpretado?

Go é uma linguagem compilada: o código-fonte é transformado diretamente em um binário nativo, sem depender de máquina virtual ou interpretador. Isso gera executáveis autossuficientes, fáceis de distribuir em contêineres, com inicialização rápida e bom desempenho, mantendo recursos como coleta de lixo automática.

O que são goroutines em Go?

Goroutines são funções executadas de forma concorrente, gerenciadas pelo runtime do Go em vez do sistema operacional. Elas são muito mais leves que threads tradicionais, permitindo criar milhares delas em um único programa. A comunicação entre goroutines acontece por canais (channels), que sincronizam e trocam dados com segurança.

## continue lendo

Continue navegando

Sobre o autor

Foto de Henrico Piubello

Henrico Piubello

Especialista de TI - Grupo Voitto · Grupo Voitto

Ver perfil e todos os artigos →