Programação Funcional em Go: do A ao Z

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Programação Funcional em Go: do A ao Z



Go (Golang) — uma linguagem frequentemente associada à programação imperativa e concorrente. No entanto, seu sistema de tipos flexível e funções de primeira classe permitem aplicar com sucesso o estilo funcional. Neste artigo, vamos explorar como usar a programação funcional (PF) em Go: desde conceitos básicos até exemplos práticos. Você aprenderá a escrever código mais limpo, previsível e testável.



O que é programação funcional no contexto do Go?



Programação funcional é um paradigma onde os cálculos são construídos com base na aplicação de funções, evitando mudanças de estado e efeitos colaterais. Em Go, isso se expressa através de:

  • Funções puras — o resultado depende apenas dos argumentos, sem mutação de dados externos.
  • Funções de alta ordem — funções que recebem outras funções como argumentos ou as retornam.
  • Closures — funções anônimas que "lembram" variáveis do escopo externo.
  • Imutabilidade de dados — preferência por cópia em vez de modificação.


Embora Go não seja uma linguagem puramente funcional (não possui mônadas ou tipos de dados algébricos), ele oferece ferramentas suficientes para o uso eficaz de abordagens de PF.



Funções anônimas e closures



Em Go, funções são objetos de primeira classe. Podem ser atribuídas a variáveis, passadas para outras funções e retornadas. Funções anônimas (lambdas) são a base do estilo funcional.



Exemplo de função anônima

package main

import "fmt"

func main() { // Função anônima atribuída a uma variável multiply := func(x, y int) int { return x * y }

result := multiply(5, 3) fmt.Println(result) // 15}


Closures

Um closure é uma função anônima que "captura" variáveis do escopo externo. É uma ferramenta poderosa para criar geradores e funções com estado.



package main

import "fmt"

// Gerador de sequênciafunc sequence() func() int { i := 0 return func() int { i++ return i }}

func main() { next := sequence() fmt.Println(next()) // 1 fmt.Println(next()) // 2 fmt.Println(next()) // 3

// Cada chamada a sequence() cria um novo closure next2 := sequence() fmt.Println(next2()) // 1}


Closures são ideais para encapsular estado sem usar variáveis globais — esta é a base da abordagem funcional em Go.



Funções puras e imutabilidade



Uma função pura não tem efeitos colaterais e não modifica os dados recebidos. Em Go, isso exige uma abordagem consciente, pois slices e maps são passados por referência.



Exemplo de função pura (sem mutação)

package main

import "fmt"

// Função pura: não modifica o slice originalfunc doubleValues(input []int) []int { result := make([]int, len(input)) for i, v := range input { result[i] = v * 2 } return result}

func main() { original := []int{1, 2, 3, 4} doubled := doubleValues(original)

fmt.Println("Original:", original) // [1 2 3 4] fmt.Println("Doubled:", doubled) // [2 4 6 8]}


Observe: criamos um novo slice em vez de modificar o original. Isso garante a imutabilidade — um princípio chave da PF.



Funções de alta ordem: map, filter, reduce

Embora Go não tenha métodos nativos map/filter/reduce para slices, é fácil implementá-los manualmente.



package main

import "fmt"

// Map — aplica uma função a cada elementofunc Map[T any](items []T, fn func(T) T) []T { result := make([]T, len(items)) for

Blogs

Book Recommendations