Como comparar valores em Go

Comparar valores é uma das operações mais comuns em qualquer linguagem de programação, e em Go não é diferente. Porém, a simplicidade da linguagem esconde algumas nuances importantes sobre como certos tipos podem ou não ser comparados diretamente.

Neste post, exploraremos os operadores de comparação em Go, suas limitações e alternativas.

Operadores de Comparação

De modo geral, Go oferece dois operadores para comparação direta de valores:

  • ==: Verifica se os valores dos dois operandos são iguais.
  • !=: Verifica se os valores dos dois operandos são diferentes.

Esses operadores funcionam para os tipos chamados de “comparáveis”, como por exemplo o boolean, int, float, tipos complexos, string, channels, arrays, structs e ponteiros.

Para os tipos numéricos (int, float e tipos complexos) também podemos utilizar >, <, <= e >=.

Leia mais »

Melhores práticas na utilização de ENUMs

Em linguagens de programação, enums (abreviação de enumerations) são amplamente utilizados para representar conjuntos de valores nomeados. No Go, embora não exista um tipo enum nativo, podemos alcançar um comportamento similar usando constantes tipadas.

Embora já haja um post aqui no blog sobre esse tema, resolvi criar uma versão atualizada dele onde iremos, além de explorar como implementar enums em Go, veremos as diferenças em relação a outras linguagens, e as melhores práticas na hora de utilizá-los.

ENUM em Go vs Outras Linguagens

Linguagens como Java e C# oferecem suporte nativo a enums, permitindo a criação de tipos enumerados com validação e métodos associados, como podemos ver no exemplo abaixo:

public enum Color {
    RED, GREEN, BLUE;
}
Leia mais »

Memory leaks em slices

Go é uma linguagem de programação reconhecida por sua eficiência e pelo gerenciamento automático de memória através do Garbage Collector (GC). No entanto, mesmo com essas vantagens, é possível que aplicações escritas em Go sofram de vazamentos de memória, especialmente quando se lida com slices de forma inadequada.

Neste post, exploraremos o que são memory leaks, como eles podem ocorrer em slices, e as melhores práticas para evitá-los.

O que é memory leak

Um memory leak (vazamento de memória) acontece quando um programa reserva espaço na memória para uso temporário e não o libera após o uso. Isso resulta em um consumo crescente de memória, podendo levar à degradação de desempenho ou até ao esgotamento da memória disponível, causando falhas na aplicação.

Em linguagens com gerenciamento automático de memória, como Go, o Garbage Collector é responsável por liberar a memória não utilizada. Porém, se houver referências ativas a áreas da memória que não são mais necessárias, o GC não consegue liberá-las, causando um vazamento de memória.

Leia mais »

Functional Options Pattern

No desenvolvimento de software, a flexibilidade na configuração de objetos é uma necessidade comum, especialmente quando lidamos com funções e estruturas que possuem múltiplos parâmetros opcionais.

Em Go, por ser uma linguagem que não suporta sobrecarga de funções e parâmetros opcionais, encontrar uma solução elegante para esse problema pode ser desafiador. É aqui que o Functional Options Pattern entra como uma abordagem eficaz e idiomática.

O que é Functional Options Pattern?

O Functional Options Pattern é um padrão de design amplamente utilizado em Go para facilitar a configuração de estruturas complexas ou funções, principalmente quando há múltiplos parâmetros opcionais. Ele permite que você construa objetos ou configure funções de maneira flexível, utilizando funções que atuam como “opções”.

Em vez de passar diretamente todos os parâmetros para o construtor ou para a função, você cria funções separadas que aplicam configurações de maneira incremental e opcional. Essa abordagem ajuda a evitar funções com longas listas de parâmetros ou a necessidade de múltiplos construtores para diferentes casos de uso.

Leia mais »

Quando utilizar generics e interfaces

A linguagem Go é amplamente conhecida por sua simplicidade e pragmatismo. O design da linguagem sempre incentivou a criação de código claro e direto, evitando abstrações desnecessárias.

Com a introdução de generics no Go 1.18, desenvolvedores agora têm mais uma ferramenta para criar abstrações poderosas e reutilizáveis. Além disso, as interfaces já desempenham um papel fundamental na criação de designs flexíveis e desacoplados.

No entanto, é preciso cautela: abstrações excessivas podem facilmente adicionar complexidade sem trazer benefícios reais.

Neste post, vamos discutir quando utilizar generics e interfaces em Go e quando é melhor evitá-los.

Leia mais »

A importância de interfaces em arquiteturas de camadas

Um código organizado é essencial para manter a facilidade em sua manutenção. Go, com sua simplicidade e eficiência, oferece diversos recursos para garantir uma arquitetura bem estruturada.

Um desses recursos é o uso de interfaces, que desempenham um papel fundamental na separação de responsabilidades e na criação de abstrações entre as camadas da aplicação.

Neste post, exploraremos como as interfaces podem ser aplicadas dentro de uma arquitetura em camadas, promovendo um código desacoplado, testável e flexível.

O que é uma arquitetura em camadas

Uma arquitetura em camadas é um padrão de design de software que divide a aplicação em diferentes camadas, onde cada uma tem uma responsabilidade específica.

Leia mais »

Por que evitar o uso da função init

Nas últimas semanas, tenho focado muito em escrever sobre o que evitar na hora de escrever programas Go.

Tenho feito isso pois, em alguns casos, o melhor que se pode saber sobre uma feature ou package é exatamente quando não utilizar.

Por isso, dando continuidade nesse tipo de post, neste, vamos explorar o que é a função init, como ela funciona, porque seu uso pode ser problemático e quando ela deve ser utilizada de forma consciente.

O que é e para que serve a função init

A função init em Go é uma função especial que é automaticamente executada pelo runtime antes da função main, sem a necessidade de ser chamada explicitamente.

Leia mais »

Por que evitar o package Reflect

O package reflect no Go é uma ferramenta poderosa que permite inspecionar e manipular tipos e valores em runtime. No entanto, como diria o tio Ben, “com grandes poderes vêm grandes responsabilidades”.

Embora possa parecer atraente em certos cenários, o uso excessivo ou inadequado do reflect pode introduzir problemas significativos no seu código, como dificuldades de manutenção, bugs difíceis de depurar e perda de performance.

Neste post, exploraremos o que é o package reflect, exemplos de sua utilização, onde ele é amplamente empregado e, mais importante, porque você deve evitá-lo quando possível.

O que é o package Reflect

O package reflect faz parte da biblioteca padrão do Go e oferece funcionalidades para inspecionar tipos e valores em runtime, ou seja, em tempo de execução.

Leia mais »

Dicas para escrever bons benchmarks

Escrever benchmarks em Go é uma prática essencial para desenvolvedores que buscam otimizar a performance de suas aplicações.

Um benchmark bem elaborado pode revelar gargalos e oportunidades de otimização que, de outra forma, poderiam passar despercebidos.

No entanto, existem armadilhas comuns que podem distorcer os resultados dos benchmarks, levando a conclusões incorretas.

Neste post, exploraremos os principais cuidados que devem ser tomados ao escrever benchmarks em Go, com exemplos de código que ilustram boas e más práticas.

Importância de escrever Benchmarks

Benchmarking é uma técnica que permite medir a eficiência de determinadas partes do código, como funções ou métodos, em termos de tempo de execução.

Ao escrever benchmarks, você pode identificar quais partes do código precisam ser otimizadas e quais já estão suficientemente rápidas. No contexto de desenvolvimento de software, benchmarks são fundamentais para garantir que mudanças no código não degradem a performance.

Leia mais »

Integrando aplicações Go com ChatGPT

Com o avanço das tecnologias de inteligência artificial, cada vez mais desenvolvedores buscam integrar suas aplicações com APIs de IA para oferecer funcionalidades avançadas e personalizadas.

Uma dessas APIs é a do ChatGPT, desenvolvida pela OpenAI, que permite gerar texto de forma natural e coerente. Neste post, vou mostrar como você pode integrar uma aplicação Go com a API do ChatGPT para criar uma funcionalidade onde o usuário insere um valor monetário e a aplicação retorna esse valor por extenso.

Pré-requisitos para a Integração

Antes de iniciar a integração, é necessário cumprir alguns pré-requisitos:

  1. Conta na OpenAI: Você precisará de uma conta na OpenAI para acessar a API do ChatGPT.
  2. API Key: Após criar sua conta, você deve gerar uma chave de API (API Key) no painel de controle da OpenAI.
Leia mais »