Programação Funcional em Go: Possibilidades e Exemplos

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: da Teoria à Prática



Go (Golang) não foi originalmente concebido como uma linguagem puramente funcional. No entanto, seu poderoso sistema de tipos, suporte a funções de primeira classe e closures permitem aplicar com sucesso os princípios da programação funcional (FP). Neste artigo, vamos explorar como usar o estilo funcional em Go para escrever código mais previsível, testável e seguro para concorrência.



1. Funções de Primeira Classe e Funções de Alta Ordem



Em Go, funções são objetos de primeira classe. Isso significa que podem ser atribuídas a variáveis, passadas como argumentos e retornadas de outras funções. Funções que trabalham com outras funções são chamadas de funções de alta ordem.



Exemplo: passando uma função como argumento



package main

import "fmt"

// Função de alta ordem: recebe uma função e a aplica a um númerofunc applyOperation(x int, op func(int) int) int { return op(x)}

func double(x int) int { return x * 2}

func square(x int) int { return x * x}

func main() { result1 := applyOperation(5, double) result2 := applyOperation(5, square)

fmt.Println("Double:", result1) // 10 fmt.Println("Square:", result2) // 25}


Exemplo: retornando uma função de outra função (fábrica de funções)



package main

import "fmt"

// Retorna uma função que adiciona um valor específicofunc createAdder(x int) func(int) int { return func(y int) int { return x + y }}

func main() { addFive := createAdder(5) addTen := createAdder(10)

fmt.Println(addFive(3)) // 8 fmt.Println(addTen(3)) // 13}


2. Closures em Go



Um closure é uma função que "lembra" variáveis do escopo externo, mesmo após esse escopo ter terminado sua execução. Closures são uma ferramenta poderosa para criar estado encapsulado e fábricas de funções.



Exemplo: gerador de sequência



package main

import "fmt"

func sequenceGenerator() func() int { i := 0 return func() int { i++ return i }}

func main() { next := sequenceGenerator()

fmt.Println(next()) // 1 fmt.Println(next()) // 2 fmt.Println(next()) // 3

// Novo gerador começa em 1 next2 := sequenceGenerator() fmt.Println(next2()) // 1}


Importante: Tenha cuidado com closures em loops. Em versões antigas do Go (anteriores à 1.22), a variável i no loop era reutilizada, o que causava erros. A partir do Go 1.22, as variáveis do loop são capturadas por valor.



3. Funções Puras e Imutabilidade



Uma função pura é uma função que:

  • Sempre retorna o mesmo resultado para os mesmos argumentos.
  • Não tem efeitos colaterais (não altera estado externo, não escreve em arquivos/rede).

Go não tem suporte nativo para imutabilidade, mas podemos seguir este princípio por conta própria.



Exemplo: função pura vs função impura



package main

import "fmt"

// Função IMPURA: altera um slice externovar counter int

func impureAddToSlice(s []int, val int) []int { counter++ // efeito colateral return append(s, val)}

// Função PURA: cria um novo slicefunc pureAddToSlice(s []int, val int) []int { newSlice := make([]int, len(s)+1) copy(newSlice, s) newSlice[len(s)] = val return newSlice}

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

// Abordagem pura result := pureAddToSlice(original, 4) fmt.Println("Original:", original) // [1 2 3] - não foi alterado fmt.Println("Result:", result) // [1 2 3 4]}


Dica: Para trabalhar com estruturas imutá

Blogs

Book Recommendations