Lista de referência do Golang

Comandos e construções úteis do Go

Conteúdo da página

Aqui está a estrutura básica de um programa Go, padrões de tratamento de erros e uma comparação entre canais e goroutines.

coelhos ao redor do sinal do golang

Folha de Consulta da Linguagem Go

Sintaxe Básica

Declaração de Pacote

package main

Importação de Pacotes

import "fmt"
import (
    "fmt"
    "math"
)

Função Principal

func main() {
    // Seu código aqui
}

Variáveis e Tipos

Declaração de Variáveis

var name string
var age int = 25
x := 10 // Declaração curta

Tipos Básicos

  • bool
  • string
  • int, int8, int16, int32, int64
  • uint, uint8, uint16, uint32, uint64
  • float32, float64
  • complex64, complex128

Estruturas de Controle

Instrução If

if x > 0 {
    // código
} else if x < 0 {
    // código
} else {
    // código
}

Loop For

for i := 0; i < 10; i++ {
    // código
}

Loop Range

for index, value := range collection {
    // código
}

Instrução Switch

switch variable {
case value1:
    // código
case value2:
    // código
default:
    // código
}

Funções

Declaração de Função

func functionName(param1 type1, param2 type2) returnType {
    // código
    return value
}

Múltiplos Valores de Retorno

func divideAndRemainder(x, y int) (int, int) {
    return x / y, x % y
}

Estruturas de Dados

Arrays

var numbers int
numbers := int{1, 2, 3, 4, 5}

Slices

slice := []int{1, 2, 3}
slice := make([]int, 3, 5)

Maps

m := make(map[string]int)
m["key"] = value

Structs

type Person struct {
    Name string
    Age  int
}
p := Person{Name: "Alice", Age: 30}

Métodos

Declaração de Método

func (r Rectangle) Area() float64 {
    return r.width * r.height
}

Interfaces

Declaração de Interface

type Shape interface {
    Area() float64
}

Concorrência

Goroutines

go functionName()

Canais

ch := make(chan int)
ch <- value  // Enviar
value := <-ch  // Receber

Tratamento de Erros

Verificação de Erros

if err != nil {
    // Tratar erro
}

Defer

defer file.Close()

Testes

Função de Teste

func TestFunction(t *testing.T) {
    // Código de teste
}

Esta folha de consulta cobre os construtos e comandos mais essenciais da linguagem Go. Inclui sintaxe básica, estruturas de controle, funções, estruturas de dados, métodos, interfaces, primitivas de concorrência e tratamento de erros. Lembre-se de que o Go enfatiza a simplicidade e a legibilidade, então esses construtos formam a base para escrever código Go eficiente e claro.

Tratamento de erros no Go

O tratamento de erros no Go é direto e explícito, enfatizando clareza e robustez. Aqui estão as técnicas principais para lidar com erros no Go:

  1. Retornar erros como valores: Funções que podem falhar devem retornar um erro como seu último valor de retorno. Por exemplo:
func Hello(name string) (string, error) {
    if name == "" {
        return "", errors.New("nome vazio")
    }
    message := fmt.Sprintf("Oi, %v. Bem-vindo!", name)
    return message, nil
}
  1. Sempre verificar erros: Após chamar uma função que retorna um erro, verifique imediatamente se o erro é não-nil. Por exemplo:
result, err := SomeFunction()
if err != nil {
    // Tratar o erro
    log.Fatal(err)
}
  1. Usar encapsulamento de erro: Ao propagar erros para cima na pilha de chamadas, encapsule-os para adicionar contexto usando fmt.Errorf() com o verbo %w. Por exemplo:
f, err := os.Open(path)
if err != nil {
    return nil, fmt.Errorf("abertura falhou: %w", err)
}
  1. Utilize defer para limpeza: Use defer para garantir que os recursos sejam fechados ou limpos corretamente, mesmo que ocorra um erro.

  2. Crie tipos de erro personalizados: Implemente a interface error para tipos de erro personalizados para fornecer informações de erro mais detalhadas.

  3. Use o pacote errors: Aproveite funções como errors.New() para criar mensagens de erro simples, e errors.Is() ou errors.As() para verificação e conversão de tipos de erro.

  4. Evite usar panic: Reserve panic para situações verdadeiramente irrecuperáveis. O tratamento de erro normal deve usar valores de retorno.

  5. Forneça informações de erro explícitas: Torne as mensagens de erro claras e informativas para ajudar na depuração e solução de problemas.

Seguindo essas práticas, você pode criar programas Go robustos que lidam com erros de forma eficaz e mantêm a clareza do código.

Melhores Práticas para Goroutines e Canais no Go

Uso Eficiente de Goroutines

  1. Evite a criação excessiva de goroutines: Crie goroutines com discernimento, considerando a natureza da tarefa e se ela se beneficia da execução paralela.

  2. Sincronização adequada: Use mecanismos de sincronização, como canais ou grupos de espera, para gerenciar goroutines de forma eficaz e evitar desperdício de recursos.

  3. Considere a natureza da tarefa: Avalie se uma tarefa realmente se beneficia da execução concorrente antes de usar goroutines.

Uso Eficaz de Canais

  1. Escolha o tipo de canal apropriado: Use canais não tamponados para sincronização e canais tamponados quando precisar desacoplar operações de envio e recebimento.

  2. Capacidade do buffer: Ao usar canais tamponados, considere cuidadosamente o tamanho do buffer para equilibrar desempenho e uso de recursos.

  3. Feche os canais corretamente: Certifique-se de que os canais sejam fechados quando não houver mais dados a serem enviados para evitar deadlocks e vazamento de recursos.

Padrões de Concorrência

  1. Padrão worker pool: Implemente pools de workers usando goroutines e canais para distribuição eficiente de tarefas e coleta de resultados.

  2. Padrão produtor-consumidor: Use goroutines como produtores e consumidores, com canais facilitando o fluxo de dados entre eles.

Tratamento de Erros e Gerenciamento de Recursos

  1. Use defer para limpeza: Empregue instruções defer para garantir a limpeza adequada de recursos, mesmo na presença de erros.

  2. Lide com panics: Implemente recover() em goroutines de longa duração para evitar que o programa inteiro trav devido a um panic em uma única goroutine.

Comunicação e Sincronização

  1. Prefira canais em vez de memória compartilhada: Use canais para comunicação entre goroutines para evitar condições de corrida e simplificar a sincronização.

  2. Use select para múltiplos canais: Empregue a instrução select para lidar com múltiplas operações de canais de forma concorrente.

Considerações de Desempenho

  1. Limite operações concorrentes: Use semáforos ou pools de workers para limitar o número de operações concorrentes e evitar esgotamento de recursos.

  2. Evite otimização prematura: Perfom seu código para identificar gargalos antes de aplicar otimizações de concorrência.

Testes e Depuração

  1. Use o detector de race conditions: Execute regularmente seus testes com a flag -race para detectar condições de corrida de dados.

  2. Escreva testes concorrentes: Crie testes que exercitem especificamente seus caminhos de código concorrente para garantir confiabilidade.

Seguindo essas melhores práticas, você pode alavancar eficazmente o modelo de concorrência do Go, tornando seus programas mais eficientes, mantíveis e menos propensos a problemas comuns relacionados à concorrência.

Veja outros artigos do blog técnico.

Atualizando o Go no Linux

  1. Vá e baixe a nova versão: https://go.dev/doc/install
  2. Remova a antiga:
sudo rm -rf /usr/local/go
  1. Instale a nova:
cd Downloads
sudo tar -C /usr/local -xzf go1.24.3.linux-amd64.tar.gz