Guia completo de Go para desenvolvimento moderno e concorrente
📖 Definição
Go é uma linguagem de programação compilada e concorrente desenvolvida pelo Google. Projetada para ser simples, eficiente e escalável, é ideal para construção de sistemas distribuídos, microserviços e aplicações de alto desempenho.
💪 Por que aprender?
• Sintaxe simples e limpa
• Tipagem estática forte
• Garbage collection
• Modelos de concorrência nativos
• Tempo de compilação rápido
• Cross-platform
🚀 O que você pode fazer?
• APIs e microserviços
• Sistemas distribuídos
• Ferramentas de linha de comando
• Aplicações em nuvem
• Networking e servidores
APIs, Microserviços
Docker, Kubernetes, Cloud
Goroutines, Canais
CLI, DevOps, SRE
🚀 Instalação e Ambiente
Use quando: Configurando ambiente Go, instalando ferramentas, configurando variáveis
📋Instalação
# Instalar Go (Linux/macOS)# Baixar e instalar
wget https://golang.org/dl/go1.21.0.linux-amd64.tar.gz# Download do Go
sudo tar -C /usr/local -xzf go1.21.0.linux-amd64.tar.gz# Extrair para /usr/local
export PATH=$PATH:/usr/local/go/bin# Adicionar ao PATH
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc# Persistir no bashrc
# Instalar Go (Windows)# Download do instalador
# Visit: https://golang.org/dl/# Baixar instalador .msi
📋Variáveis de Ambiente
go version# Verificar versão instalada
go env# Ver todas as variáveis de ambiente
go env GOPATH# Ver GOPATH
go env GOROOT# Ver GOROOT
go env GOOS# Ver sistema operacional
go env GOARCH# Ver arquitetura
export GOPATH=$HOME/go# Configurar GOPATH
export PATH=$PATH:$GOPATH/bin# Adicionar GOPATH/bin ao PATH
📋Ferramentas
go help# Ajuda geral do Go
go help command# Ajuda de comando específico
go tool# Listar ferramentas disponíveis
go doc# Documentação local
go fmt# Formatador de código
go vet# Analisador estático
go mod# Gerenciador de módulos
📁 Estrutura de Projetos
Use quando: Criando novos projetos, organizando código, gerenciando dependências
📋Módulos Go
go mod init example.com/myproject# Iniciar novo módulo
go mod init github.com/user/project# Módulo no GitHub
go mod tidy# Organizar dependências
go mod download# Baixar dependências
go mod verify# Verificar dependências
go mod why example.com/pkg# Por que pacote é necessário
go list -m all# Listar todos os módulos
go mod graph# Gráfico de dependências
📋Estrutura de Diretórios
mkdir -p cmd/myapp# Aplicações principais
mkdir -p pkg/utils# Bibliotecas reutilizáveis
mkdir -p internal/config# Código interno
mkdir -p api/proto# Definições de API
mkdir -p web/static# Assets web
mkdir -p deployments# Configurações deploy
mkdir -p scripts# Scripts utilitários
mkdir -p docs# Documentação
📋Build e Execução
go run main.go# Executar diretamente
go run .# Executar pacote atual
go run cmd/myapp/main.go# Executar aplicação específica
go build# Compilar para binário
go build -o myapp# Compilar com nome customizado
go build -o myapp main.go# Compilar arquivo específico
go install# Compilar e instalar em GOPATH/bin
go clean# Limpar arquivos de build
📋Cross-compilation
GOOS=linux go build# Build para Linux
GOOS=windows go build# Build para Windows
GOOS=darwin go build# Build para macOS
GOOS=linux GOARCH=arm64 go build# Build para ARM64
GOOS=windows GOARCH=amd64 go build# Build Windows 64-bit
go build -ldflags="-s -w"# Build otimizado
go build -tags netgo -installsuffix netgo# Build com CGO desabilitado
📋 Variáveis e Tipos
Use quando: Declarando variáveis, trabalhando com tipos básicos, definindo constantes
📋Declaração de Variáveis
var nome string = "João"# Declaração completa
var idade int = 25# Tipo inteiro
var altura float64 = 1.75# Ponto flutuante
var ativo bool = true# Booleano
nome := "Maria"# Inferência de tipo (short declaration)
idade := 30# Inferência para inteiro
var preco = 19.99# Inferência sem tipo explícito
var cidade string# Declaração sem valor (zero value)
📋Tipos Básicos
var nome string# String
var idade int# Inteiro
var preco float64# Float 64-bit
var flag bool# Booleano
var byteVar byte# Byte (uint8)
var runeVar rune# Rune (int32)
var erro error# Tipo error
var ptr *int# Ponteiro para inteiro
📋Tipos Numéricos
var i int# Inteiro (depende da arquitetura)
var i8 int8# Inteiro 8-bit
var i16 int16# Inteiro 16-bit
var i32 int32# Inteiro 32-bit
var i64 int64# Inteiro 64-bit
var u uint# Unsigned int
var u32 uint32# Unsigned 32-bit
var u64 uint64# Unsigned 64-bit
var f32 float32# Float 32-bit
var f64 float64# Float 64-bit
📋Constantes
const PI = 3.14159# Constante numérica
const nome = "Go"# Constante string
const ativo = true# Constante booleana
const (
A = 1
B = 2
C = 3
)# Bloco de constantes
const (
Segunda = iota
Terça
Quarta
)# iota (auto-incremento)
🏗️ Estruturas de Dados
Use quando: Trabalhando com coleções de dados, estruturas complexas, armazenamento
📋Arrays
var numeros [5]int# Array de 5 inteiros
numeros := [5]int{1, 2, 3, 4, 5}# Array com valores
numeros := [...]int{1, 2, 3, 4, 5}# Array com tamanho automático
primeiro := numeros[0]# Acessar elemento
len(numeros)# Tamanho do array
var matriz [3][4]int# Array multidimensional
📋Slices
var slice []int# Slice vazio
slice := []int{1, 2, 3, 4, 5}# Slice com valores
slice := make([]int, 5)# Slice com make()
slice := make([]int, 5, 10)# Com capacidade
slice = append(slice, 6)# Adicionar elemento
slice = append(slice, 7, 8, 9)# Adicionar múltiplos
subslice := slice[1:4]# Fatiar slice
subslice := slice[:3]# Primeiros 3 elementos
subslice := slice[2:]# Do 2 até o fim
📋Maps
var m map[string]int# Map vazio
m := make(map[string]int)# Criar map com make()
m := map[string]int{"a": 1, "b": 2}# Map com valores
m["chave"] = 42# Adicionar/alterar valor
valor := m["chave"]# Acessar valor
valor, ok := m["chave"]# Acessar com verificação
delete(m, "chave")# Remover chave
len(m)# Número de elementos
📋Structs
type Pessoa struct {
Nome string
Idade int
}# Definir struct
p := Pessoa{Nome: "João", Idade: 25}# Criar instância
p := Pessoa{"Maria", 30}# Criar sem nome de campos
var p Pessoa# Struct vazia (zero values)
p.Nome = "Carlos"# Acessar campo
nome := p.Nome# Ler campo
type Endereco struct {
Rua, Cidade string
CEP int
}# Campos combinados
🔀 Estruturas de Controle
Use quando: Controlando fluxo do programa, repetições, decisões condicionais
📋If/Else
if idade >= 18 {
fmt.Println("Maior de idade")
}# If simples
if nota >= 7 {
fmt.Println("Aprovado")
} else {
fmt.Println("Reprovado")
}# If/Else
if nota >= 7 {
fmt.Println("Aprovado")
} else if nota >= 5 {
fmt.Println("Recuperação")
} else {
fmt.Println("Reprovado")
}# If/Else If/Else
if valor := calcular(); valor > 0 {
fmt.Println("Positivo:", valor)
}# If com inicialização
📋Loops For
for i := 0; i < 5; i++ {
fmt.Println(i)
}# For tradicional
for i := 1; i <= 10; i += 2 {
fmt.Println(i)
}# For com passo
i := 0
for i < 5 {
fmt.Println(i)
i++
}# For como while
slice := []int{1, 2, 3}
for i, valor := range slice {
fmt.Println(i, valor)
}# Range em slice
m := map[string]int{"a": 1, "b": 2}
for chave, valor := range m {
fmt.Println(chave, valor)
}# Range em map
for i := range 5 {
fmt.Println(i)
}# Range simples
for {
// loop infinito
}# Loop infinito
📋Switch
switch dia {
case "segunda":
fmt.Println("Início da semana")
case "sexta":
fmt.Println("Final da semana")
default:
fmt.Println("Meio da semana")
}# Switch básico
switch nota {
case 10:
fmt.Println("Perfeito")
case 9, 8:
fmt.Println("Ótimo")
case 7, 6:
fmt.Println("Bom")
default:
fmt.Println("Precisa melhorar")
}# Múltiplos casos
x := 10
switch {
case x > 10:
fmt.Println("Maior que 10")
case x == 10:
fmt.Println("Igual a 10")
default:
fmt.Println("Menor que 10")
}# Switch sem expressão
📋Break e Continue
for i := 0; i < 10; i++ {
if i == 5 {
continue
}
fmt.Println(i)
}# Continue - pular iteração
for i := 0; i < 10; i++ {
if i == 7 {
break
}
fmt.Println(i)
}# Break - sair do loop
Loop:
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
if i == j {
break Loop
}
fmt.Println(i, j)
}
}# Break com label
⚡ Funções
Use quando: Reutilizando código, organização lógica, modularização, closures
📋Funções Básicas
func saudar(nome string) {
fmt.Println("Olá,", nome)
}# Função simples
func soma(a, b int) int {
return a + b
}# Função com retorno
func calcula(base, altura float64) (float64, float64) {
area := base * altura
perimetro := 2 * (base + altura)
return area, perimetro
}# Múltiplos retornos
func saudar(nome string, idade ...int) {
fmt.Println("Olá,", nome)
for _, i := range idade {
fmt.Println(i)
}
}# Variadic arguments
📋Funções Anônimas
soma := func(a, b int) int {
return a + b
}
resultado := soma(3, 4)# Função anônima
func executor(f func(int) int, valor int) {
fmt.Println(f(valor))
}
quadrado := func(x int) int { return x * x }
executor(quadrado, 5)# Função como parâmetro
func() {
fmt.Println("Executando imediatamente")
}()# IIFE (Immediately Invoked)
📋Closures
func contador() func() int {
i := 0
return func() int {
i++
return i
}
}
c := contador()
fmt.Println(c()) // 1
fmt.Println(c()) // 2# Closure simples
func multiplicador(fator int) func(int) int {
return func(x int) int {
return x * fator
}
}
dobrar := multiplicador(2)
triplicar := multiplicador(3)# Closure factory
📋Recursão
func fatorial(n int) int {
if n <= 1 {
return 1
}
return n * fatorial(n-1)
}# Função recursiva
func fibonacci(n int) int {
if n <= 1 {
return n
}
return fibonacci(n-1) + fibonacci(n-2)
}# Fibonacci recursivo
func fibonacciIterativo(n int) int {
a, b := 0, 1
for i := 0; i < n; i++ {
a, b = b, a+b
}
return a
}# Versão iterativa (mais eficiente)
🔧 Métodos e Interfaces
Use quando: Polimorfismo, abstração, padrões de projeto, design flexível
📋Métodos
type Retangulo struct {
Largura, Altura float64
}
func (r Retangulo) Area() float64 {
return r.Largura * r.Altura
}# Método em struct
func (r *Retangulo) SetLargura(l float64) {
r.Largura = l
}# Método com ponteiro
type Celsius float64
func (c Celsius) Fahrenheit() float64 {
return float64(c)*9/5 + 32
}# Método em tipo básico
type Contador int
func (c *Contador) Incrementar() {
*c++
}# Método em tipo customizado
📋Interfaces
type Forma interface {
Area() float64
Perimetro() float64
}# Definir interface
type Escritor interface {
Escrever() error
}
type Arquivo struct{}
func (a Arquivo) Escrever() error {
// implementação
return nil
}# Implementar interface
type InterfaceVazia interface{}
func QualquerCoisa(valor interface{}) {
// aceita qualquer tipo
}# Interface vazia (any)
var w Escritor = Arquivo{}
w.Escrever()# Usar interface
📋Type Assertions
var x interface{} = "hello"
if s, ok := x.(string); ok {
fmt.Println("String:", s)
}# Type assertion com verificação
valor := x.(string)# Type assertion direto (pode panicar)
switch v := x.(type) {
case string:
fmt.Println("String:", v)
case int:
fmt.Println("Int:", v)
default:
fmt.Println("Tipo desconhecido")
}# Type switch
📋Interfaces Comuns
type Stringer interface {
String() string
}# Interface Stringer
type Error interface {
Error() string
}# Interface Error
func (e ErroCustom) Error() string {
return "Erro: " + e.mensagem
}# Implementar Error
fmt.Println(erroCustom)# Print chama String() ou Error()
🚀 Goroutines e Canais
Use quando: Processamento concorrente, paralelismo, comunicação entre goroutines
📋Goroutines
go func() {
fmt.Println("Executando em goroutine")
}()# Goroutine anônima
func tarefa(id int) {
fmt.Println("Tarefa", id)
}
for i := 0; i < 3; i++ {
go tarefa(i)
}# Múltiplas goroutines
func tarefaLonga() {
time.Sleep(2 * time.Second)
fmt.Println("Pronto")
}
fmt.Println("Iniciando")
go tarefaLonga()
fmt.Println("Continuando")
time.Sleep(3 * time.Second)# Goroutine com delay
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
fmt.Println("Tarefa", id)
}(i)
}
wg.Wait()# WaitGroup para sincronização
📋Canais Básicos
ch := make(chan int)# Criar canal
ch <- 42# Enviar para canal
valor := <-ch# Receber do canal
ch := make(chan string, 10)# Canal com buffer
close(ch)# Fechar canal
valor, ok := <-ch# Receber com verificação
📋Select
select {
case msg1 := <-ch1:
fmt.Println("Recebido:", msg1)
case msg2 := <-ch2:
fmt.Println("Recebido:", msg2)
case ch3 <- mensagem:
fmt.Println("Enviado")
default:
fmt.Println("Nenhum canal pronto")
}# Select com múltiplos casos
select {
case <-time.After(2 * time.Second):
fmt.Println("Timeout")
case valor := <-ch:
fmt.Println("Recebido:", valor)
}# Select com timeout
ticker := time.NewTicker(1 * time.Second)
for {
select {
case <-ticker.C:
fmt.Println("Tick")
case <-done:
return
}
}Select com ticker
📋Padrões de Concorrência
func worker(jobs <-chan int, results chan<- int) {
for j := range jobs {
results <- j * 2
}
}# Worker pool pattern
jobs := make(chan int, 100)
results := make(chan int, 100)
for w := 0; w < 3; w++ {
go worker(jobs, results)
}
for j := 0; j < 5; j++ {
jobs <- j
}
close(jobs)# Usando worker pool
func fanIn(input1, input2 <-chan string) <-chan string {
output := make(chan string)
go func() {
for {
select {
case s := <-input1:
output <- s
case s := <-input2:
output <- s
}
}
}()
return output
}# Fan-in pattern
⚠️ Error Handling
Use quando: Tratamento de erros robusto, validação, recuperação de panics
📋Errors Básicos
func dividir(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("divisão por zero")
}
return a / b, nil
}# Função que retorna error
resultado, err := dividir(10, 0)
if err != nil {
fmt.Println("Erro:", err)
return
}
fmt.Println("Resultado:", resultado)# Tratamento de error
import "errors"
err := errors.New("erro customizado")# Criar error simples
err := fmt.Errorf("valor %d inválido", valor)# Error formatado
📋Errors Customizados
type ErroValidacao struct {
Campo string
Valor interface{}
}
func (e ErroValidacao) Error() string {
return fmt.Sprintf("campo %s inválido: %v", e.Campo, e.Valor)
}# Struct de error customizado
type ErroNegocio struct {
Code int
Message string
}
func (e ErroNegocio) Error() string {
return fmt.Sprintf("Erro %d: %s", e.Code, e.Message)
}# Error de negócio
func validarIdade(idade int) error {
if idade < 0 {
return ErroValidacao{"idade", idade}
}
return nil
}# Usar error customizado
📋Wrapping Errors
func processarArquivo(arquivo string) error {
data, err := os.ReadFile(arquivo)
if err != nil {
return fmt.Errorf("falha ao ler arquivo %s: %w", arquivo, err)
}
// processar data
return nil
}# Error wrapping
err := processarArquivo("dados.txt")
if err != nil {
if errors.Is(err, os.ErrNotExist) {
fmt.Println("Arquivo não existe")
} else {
fmt.Println("Outro erro:", err)
}
}# Verificar error com errors.Is
var pathError *os.PathError
if errors.As(err, &pathError) {
fmt.Println("Erro de caminho:", pathError.Path)
}Extrair tipo específico com errors.As
📋Panic e Recover
panic("algo deu muito errado!")# Disparar panic
func dangerous() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recuperado do panic:", r)
}
}()
panic("problema!")
}# Recover de panic
func devePanic(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Errorf("Esperava panic")
}
}()
funcaoQueDevePanicar()
}# Testar panic em unit tests
🧪 Testing
Use quando: Desenvolvimento orientado a testes, garantia de qualidade, regressão
📋Testes Básicos
func TestSoma(t *testing.T) {
resultado := soma(2, 3)
esperado := 5
if resultado != esperado {
t.Errorf("soma(2, 3) = %d; esperado %d", resultado, esperado)
}
}# Teste básico
go test# Executar todos os testes
go test -v# Executar com verbosidade
go test -run TestSoma# Executar teste específico
go test ./...# Executar testes em todos os pacotes
📋Assertions
func TestDivisao(t *testing.T) {
t.Run("divisão normal", func(t *testing.T) {
resultado, err := dividir(10, 2)
if resultado != 5 {
t.Errorf("Esperado 5, obteve %f", resultado)
}
if err != nil {
t.Errorf("Não deveria ter erro: %v", err)
}
})
}# Subtestes
if !reflect.DeepEqual(resultado, esperado) {
t.Errorf("Resultados diferentes")
}# Comparar structs complexas
if len(slices) != 3 {
t.Errorf("Esperado 3 elementos, obteve %d", len(slices))
}# Verificar tamanho
📋Teste de Erros
func TestDivisaoPorZero(t *testing.T) {
_, err := dividir(10, 0)
if err == nil {
t.Error("Esperava erro de divisão por zero")
}
if err.Error() != "divisão por zero" {
t.Errorf("Mensagem de erro inesperada: %s", err.Error())
}
}# Testar erro
func TestErroCustomizado(t *testing.T) {
err := processar(-1)
var erroValidacao ErroValidacao
if !errors.As(err, &erroValidacao) {
t.Errorf("Esperava ErroValidacao, obteve %T", err)
}
}# Testar error customizado
📋Benchmark
func BenchmarkSoma(b *testing.B) {
for i := 0; i < b.N; i++ {
soma(100, 200)
}
}# Benchmark de performance
go test -bench=.# Executar benchmarks
go test -bench=BenchmarkSoma -benchmem# Benchmark com memória
go test -bench=. -cpuprofile=cpu.prof# Profile de CPU
go test -bench=. -memprofile=mem.prof# Profile de memória
📋Table-driven Tests
func TestCalculadora(t *testing.T) {
casos := []struct {
nome string
a, b int
esperado int
}{
{"soma positiva", 2, 3, 5},
{"soma negativa", -2, -3, -5},
{"soma zero", 0, 5, 5},
}
for _, c := range casos {
t.Run(c.nome, func(t *testing.T) {
resultado := soma(c.a, c.b)
if resultado != c.esperado {
t.Errorf("%s: soma(%d, %d) = %d; esperado %d",
c.nome, c.a, c.b, resultado, c.esperado)
}
})
}
}# Table-driven test
⏱️ Context e Cancelamento
Use quando: Operações longas, cancelamento propagação, timeouts em APIs
📋Context Básico
import "context"
ctx := context.Background()# Context raiz
ctx := context.TODO()# Context placeholder
ctx, cancel := context.WithCancel(context.Background())
defer cancel()# Context com cancelamento
ctx := context.WithValue(context.Background(), "userID", 123)# Context com valores
📋Timeout
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
select {
case <-ctx.Done():
fmt.Println("Timeout:", ctx.Err())
case resultado := <-longaOperacao():
fmt.Println("Sucesso:", resultado)
}# Context com timeout
func operacaoLonga(ctx context.Context) error {
select {
case <-time.After(10 * time.Second):
return nil
case <-ctx.Done():
return ctx.Err()
}
}# Função que respeita context
📋Cancelamento
ctx, cancel := context.WithCancel(context.Background())
go func() {
time.Sleep(2 * time.Second)
cancel() // cancela após 2 segundos
}()
select {
case <-ctx.Done():
fmt.Println("Cancelado:", ctx.Err())
}# Cancelamento manual
func worker(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("Worker encerrado")
return
default:
// fazer trabalho
time.Sleep(100 * time.Millisecond)
}
}
}# Worker com cancelamento
📋Propagação de Context
func handler(ctx context.Context) error {
ctx = context.WithValue(ctx, "requestID", "12345")
return servico(ctx)
}
func servico(ctx context.Context) error {
requestID := ctx.Value("requestID").(string)
fmt.Println("Request ID:", requestID)
return nil
}# Propagar valores
func servidorHTTP(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx = context.WithValue(ctx, "userID", getUserID(r))
processarRequisicao(ctx)
}# Context em HTTP
📋Deadline
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second))
defer cancel()# Context com deadline
if deadline, ok := ctx.Deadline(); ok {
fmt.Println("Deadline:", deadline)
tempoRestante := time.Until(deadline)
fmt.Println("Tempo restante:", tempoRestante)
}# Verificar deadline
func tarefaComDeadline(ctx context.Context) error {
if deadline, ok := ctx.Deadline(); ok {
fmt.Println("Precisa terminar antes:", deadline)
}
// executar tarefa
return nil
}# Tarefa com deadline
🔍 Reflection e Generics
Use quando: Frameworks, bibliotecas genéricas, metaprogramação, serialização
📋Reflection Básica
import "reflect"
x := 42
tipo := reflect.TypeOf(x)
valor := reflect.ValueOf(x)
fmt.Println("Tipo:", tipo)
fmt.Println("Valor:", valor)# Type e Value
var i int = 42
v := reflect.ValueOf(i)
if v.Kind() == reflect.Int {
fmt.Println("É um inteiro")
}# Verificar kind
pessoa := Pessoa{Nome: "João", Idade: 25}
v := reflect.ValueOf(pessoa)
campo := v.FieldByName("Nome")
fmt.Println("Nome:", campo.String())# Acessar campos
📋Modificação com Reflection
x := 42
v := reflect.ValueOf(&x).Elem()
if v.CanSet() {
v.SetInt(100)
fmt.Println("x agora é:", x)
}# Modificar valor
slice := []int{1, 2, 3}
v := reflect.ValueOf(slice)
v.SetLen(5)
fmt.Println("Novo tamanho:", len(slice))# Modificar slice
m := make(map[string]int)
v := reflect.ValueOf(m)
v.SetMapIndex(reflect.ValueOf("chave"), reflect.ValueOf(42))# Modificar map
📋Generics
func Generico[T any](valor T) T {
return valor
}# Função genérica simples
type Pilha[T any] struct {
elementos []T
}
func (p *Pilha[T]) Push(elemento T) {
p.elementos = append(p.elementos, elemento)
}
func (p *Pilha[T]) Pop() T {
ultimo := p.elementos[len(p.elementos)-1]
p.elementos = p.elementos[:len(p.elementos)-1]
return ultimo
}# Struct genérica
func Maior[T constraints.Ordered](a, b T) T {
if a > b {
return a
}
return b
}# Generics com constraints
📋Interfaces Genéricas
type Container[T any] interface {
Add(T)
Get() T
}# Interface genérica
type Comparavel interface {
Compare(outro interface{}) int
}
func Max[T Comparavel](slice []T) T {
max := slice[0]
for _, v := range slice[1:] {
if v.Compare(max) > 0 {
max = v
}
}
return max
}# Interface com generics
📋Reflection e Generics
func ImprimirTipo[T any](valor T) {
t := reflect.TypeOf(valor)
v := reflect.ValueOf(valor)
fmt.Printf("Tipo: %s, Valor: %v\n", t, v)
}# Reflection em genéricos
func CriarSlice[T any](tipo T, tamanho int) []T {
t := reflect.TypeOf(tipo)
slice := reflect.MakeSlice(reflect.SliceOf(t), tamanho, tamanho)
return slice.Interface().([]T)
}# Criar slices dinamicamente
🏗️ Build e Deployment
Use quando: Produção, CI/CD, Docker, deployment em diferentes plataformas
📋Build Options
go build -ldflags="-s -w"# Strip symbols (binário menor)
go build -ldflags="-X main.Version=1.0.0"# Injetar variáveis
go build -tags "production"# Build tags
go build -race# Detector de race conditions
go build -gcflags="-m"# Mostrar optimizations do compilador
go build -asmflags="-I ."# Flags para assembler
📋Cross-compilation
GOOS=linux GOARCH=amd64 go build# Linux 64-bit
GOOS=windows GOARCH=amd64 go build -o app.exe# Windows 64-bit
GOOS=darwin GOARCH=amd64 go build# macOS Intel
GOOS=darwin GOARCH=arm64 go build# macOS Apple Silicon
GOOS=linux GOARCH=arm64 go build# Linux ARM64
GOOS=freebsd GOARCH=amd64 go build# FreeBSD
📋Docker
# Multi-stage build
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o main .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/main .
CMD ["./main"]# Docker multi-stage
FROM golang:1.21-alpine AS builder
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .# Build para Alpine
📋CI/CD
name: Test and Build
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.21'
- run: go test ./...# GitHub Actions
build:
stage: build
image: golang:1.21
script:
- go mod download
- go build -o app
artifacts:
paths:
- app# GitLab CI
pipeline:
agent:
docker:
image: golang:1.21
steps:
- checkout
- task: Test
script:
- go test ./...# Bamboo
📋Deployment
systemctl start myapp.service# Systemd service
docker-compose up -d# Docker Compose
kubectl apply -f deployment.yaml# Kubernetes
docker build -t myapp:latest .# Docker image
docker push registry.com/myapp:latest# Push para registry
🤝 Contribuindo
Encontrou um erro? Quer melhorar um cheatsheet? Tem uma sugestão? Adoraríamos suas contribuições! Abra uma issue ou submeta um PR.
Gostou do projeto? Apoie o desenvolvimento com um café e ajude a manter tudo open source ☕