Desafio Go
Enum com String e Bit Flags com Verificação de Múltiplas Flags
Enunciado
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().
Requisitos
- Definir
type Nivel intetype Permissao uint. - Usar
iotapara o enumNivele1 << iotapara as permissões. - Implementar
String() stringparaNivel. - Verificar a presença de
LereEscreverna permissãope imprimir os resultados. - Imprimir o nível
AltousandoString().
Código inicial
package main
import "fmt"
// TODO: defina Nivel, Permissao e seus métodos
func main() {
// TODO: implemente a lógica
}
Saída esperada
Tem leitura? true
Tem escrita? false
Nível: Alto
Ver dica
Para o método String de Nivel, use um array de strings indexado pelo valor do nível. Para as permissões, use p&Ler != 0.
Mostrar solução
package main
import "fmt"
type Nivel int
const (
Baixo Nivel = iota // 0
Medio // 1
Alto // 2
)
// String implementa fmt.Stringer para Nivel.
func (n Nivel) String() string {
niveis := [...]string{"Baixo", "Medio", "Alto"}
if n < Baixo || n > Alto {
return fmt.Sprintf("Nivel(%d)", int(n))
}
return niveis[n]
}
type Permissao uint
const (
Ler Permissao = 1 << iota // 1 << 0 = 1
Escrever // 1 << 1 = 2
Executar // 1 << 2 = 4
)
func main() {
p := Ler | Executar // 1 | 4 = 5
fmt.Println("Tem leitura?", p&Ler != 0)
fmt.Println("Tem escrita?", p&Escrever != 0)
fmt.Println("Nível:", Alto)
}
Passo a passo
- Definimos
type Nivel inte o blococonstcomiotaparaBaixo,Medio,Alto(0, 1, 2). - Implementamos
String() stringparaNivelusando um array de strings e verificação de limites. - Definimos
type Permissao uinte o blococonstcom1 << iotaparaLer,Escrever,Executar(1, 2, 4). - No
main, criamosp := Ler | Executar(1 | 4 = 5). - Verificamos a presença de
LereEscrevercomp&Ler != 0ep&Escrever != 0. - Imprimimos
Alto, que chama automaticamente o métodoString().
Por que funciona
O iota gera valores sequenciais para o enum, e o método String() permite uma representação legível. Para as permissões, cada flag é uma potência de dois, permitindo combinações com | e verificações com &. A verificação p&flag != 0 isola o bit correspondente.
Erros comuns
- Não implementar
String()corretamente: se o array não cobrir todos os valores, pode causar panic. Sempre verifique os limites. - Usar
p&Ler == 1em vez de!= 0: funciona aqui, mas se a flag tiver múltiplos bits, a comparação falha. Prefira!= 0. - Esquecer de tipar a primeira constante do bloco
constde permissões:Ler = 1 << iotasemPermissaofaria as constantes seremintnão tipadas, quebrando a tipagem forte.
Outra forma de resolver
Para verificar múltiplas flags de uma vez, use p&(Ler|Escrever) == (Ler|Escrever). Isso é útil quando você precisa que todas estejam presentes.
Saída esperada
Tem leitura? true
Tem escrita? false
Nível: Alto