No coração de um computador, o processamenot é feito usando zeros e uns. Os operadores bitwise na linguagem Go permitem que os desenvolvedores interajam diretamente com esta representação binária de números inteiros. Esta operação de baixo nível é essencial para tarefas de alta performance, manipulação de hardware e otimizações algorítmicas.
A linguagem Go oferece seis operadores bitwise principais que funcionam em tipos de dados inteiros. Estes operadores permitem a manipulação de bits individuais dentro de uma variável.
Vamos começar com um exemplo básico para visualizar a representação binária:
package main
import "fmt"
func main() {
var valor1 uint8 = 0b11001010 // Binário: 202
var valor2 uint8 = 0b10110101 // Binário: 181
fmt.Printf("valor1: %08b (%d)\n", valor1, valor1)
fmt.Printf("valor2: %08b (%d)\n", valor2, valor2)
}
- Operador AND Bitwise (&)
O operador AND retorna 1 em uma posição de bit apenas se ambos os bits correspondentes das duas entradas forem 1. Ele é frequentemente usado para "ligar" bits específicos ou criar máscaras de bits.
Regras:
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
Exemplo Prático:
func main() {
var a uint8 = 0b11001010 // 202
var b uint8 = 0b10110101 // 181
resultado := a & b
fmt.Printf("a & b = %08b (%d)\n", resultado, resultado) // 10000000 (128)
}
Aplicação comum: Verificar se um bit específico está definido.
func temPermissao(permissoes uint8, mascaraPermissao uint8) bool {
return (permissoes & mascaraPermissao) != 0
}
func main() {
const permissaoLeitura = 0b00000001
permissoesUsuario := uint8(0b00000111) // Tem permissões 1, 2 e 4
if temPermissao(permissoesUsuario, permissaoLeitura) {
fmt.Println("O usuário possui permissão de leitura.")
}
}
- Operador OR Bitwise (|)
O operador OR retorna 1 se pelo menos um dos bits na mesma posição for 1. É a ferramenta para "ativar" bits específicos em uma variável.
Regras:
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
Exemplo Prático:
func main() {
var x uint8 = 0b11001010 // 202
var y uint8 = 0b00110101 // 53
resultado := x | y
fmt.Printf("x | y = %08b (%d)\n", resultado, resultado) // 11111111 (255)
}
Aplicação comum: Definir múltiplas flags ou opções em um único valor.
func main() {
const (
FlagNegrito = 1 << iota // 1 (0001)
FlagItalico // 2 (0010)
FlagSublinhado // 4 (0100)
)
// `iota` é um contador automático em blocos `const`.
estiloDoTexto := uint8(FlagNegrito | FlagItalico) // Combina flags: 3 (0011)
fmt.Printf("Estilo do texto: %08b\n", estiloDoTexto)
// Verificando uma flag específica
if estiloDoTexto&FlagItalico != 0 {
fmt.Println("O texto está em itálico.")
}
}