Da trilha de Go Este conceito ainda não saiu como card do dia. ir para o card de hoje

Go Fundamentos Básico

Constantes e iota

Em Go, constantes são valores imutáveis definidos em tempo de compilação. Elas podem ser tipadas (com um tipo explícito) ou não tipadas (sem tipo declarado, assumindo o tipo padrão quando necessário). Constantes não tipadas oferecem maior flexibilidade em expressões.

O identificador pré-declarado iota é usado em declarações const para gerar uma sequência de valores inteiros incrementais. Ele é reiniciado a cada bloco const e incrementa a cada linha (ou grupo de linhas) dentro do bloco. Isso permite criar enums idiomáticos de forma concisa.

Além disso, iota combinado com deslocamentos bit a bit (1 << iota) é a maneira idiomática de definir bit flags, onde cada constante representa um único bit em um campo de bits. Essas flags podem ser combinadas com operadores bit a bit (|, &, ^) para representar conjuntos de opções.

Neste card, você aprenderá a declarar constantes tipadas e não tipadas, usar iota para enums e bit flags, e aplicar essas técnicas em situações práticas.

Pontos-chave

  • Constantes são imutáveis e avaliadas em tempo de compilação.
  • const pode ser tipada (const X int = 10) ou não tipada (const X = 10).
  • iota incrementa automaticamente dentro de um bloco const, começando em 0.
  • Enums em Go são criados com iota e um tipo personalizado (ex.: type Dia int).
  • Bit flags usam 1 << iota para definir potências de dois.
const_iota.go
package main

import "fmt"

// Constantes não tipadas (sem tipo explícito)
const (
	Nome    = "Go"
	Versao  = 1.21
	Ativo   = true
)

// Constante tipada
const Pi float64 = 3.14159

// Enum idiomático com iota
type Dia int

const (
	Domingo Dia = iota // 0
	Segunda            // 1
	Terca              // 2
	Quarta             // 3
	Quinta             // 4
	Sexta              // 5
	Sabado             // 6
)

// Bit flags com iota e deslocamento
type Permissao uint

const (
	Ler    Permissao = 1 << iota // 1 << 0 = 1
	Escrever                     // 1 << 1 = 2
	Executar                     // 1 << 2 = 4
)

func main() {
	fmt.Println("Nome:", Nome)
	fmt.Println("Versao:", Versao)
	fmt.Println("Ativo:", Ativo)
	fmt.Println("Pi:", Pi)

	fmt.Println("\nDias da semana:")
	for d := Domingo; d <= Sabado; d++ {
		fmt.Printf("%d: %s\n", d, d)
	}

	fmt.Println("\nPermissões:")
	p := Ler | Escrever
	fmt.Println("Permissão:", p)
	fmt.Println("Tem leitura?", p&Ler != 0)
	fmt.Println("Tem execução?", p&Executar != 0)
}

// String method para o tipo Dia (para impressão amigável)
func (d Dia) String() string {
	dias := [...]string{"Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"}
	if d < Domingo || d > Sabado {
		return fmt.Sprintf("Dia(%d)", int(d))
	}
	return dias[d]
}

Exercícios

  1. 1
    Fácil

    Enum de Status com iota

    Crie um tipo Status (int) e use iota para definir constantes: Pendente, EmAndamento, Concluido e Cancelado. Em seguida, no main, imprima o valor numérico de cada status.

    Resolver
  2. 2
    Médio

    Bit Flags para Permissões

    Defina um tipo Permissao (uint) e use iota com deslocamento bit a bit para criar as flags Ler, Escrever e Executar. No main, crie uma permissão combinada Ler | Escrever, verifique se ela contém Ler e Executar, e imprima os resultados.

    Resolver
  3. 3
    Desafio

    Enum com String e Bit Flags com Verificação de Múltiplas Flags

    Crie um enum Nivel (int) com Baixo, Medio, Alto usando iota. Implemente o método String() para Nivel. Defina também um tipo Permissao (uint) com as flags Ler, Escrever, Executar usando 1 << iota. No main, crie uma permissão p := Ler | Executar, verifique se ela contém Ler e Escrever (imprima true ou false para cada), e imprima o nível Alto usando seu método String().

    Resolver

Continue estudando