Tipos básicos: int, float, string, bool e zero values
1. Introdução aos tipos básicos em Go
Go é uma linguagem de tipagem estática e forte, o que significa que todos os tipos de variáveis são conhecidos em tempo de compilação e não há conversões implícitas entre tipos diferentes. Essa característica traz benefícios significativos para performance e segurança do código, pois muitos erros são capturados durante a compilação, antes mesmo da execução.
Os tipos básicos em Go formam a fundação sobre a qual toda a linguagem é construída. Compreendê-los em profundidade é essencial para escrever código eficiente e correto. Neste artigo, exploraremos os cinco tipos fundamentais: inteiros, floats, strings, booleanos e seus respectivos zero values.
2. Tipos inteiros (int)
Go oferece uma família rica de tipos inteiros, divididos em duas categorias principais: com sinal (signed) e sem sinal (unsigned).
Tipos com sinal:
- int8: -128 a 127
- int16: -32.768 a 32.767
- int32: -2.147.483.648 a 2.147.483.647
- int64: -9.223.372.036.854.775.808 a 9.223.372.036.854.775.807
- int: tamanho dependente da arquitetura (32 bits em sistemas 32-bit, 64 bits em sistemas 64-bit)
Tipos sem sinal:
- uint8: 0 a 255
- uint16: 0 a 65.535
- uint32: 0 a 4.294.967.295
- uint64: 0 a 18.446.744.073.709.551.615
- uint: tamanho dependente da arquitetura
package main
import (
"fmt"
"unsafe"
)
func main() {
var a int = 42
var b int32 = 100
var c uint8 = 255
fmt.Printf("int: valor=%d, tamanho=%d bytes\n", a, unsafe.Sizeof(a))
fmt.Printf("int32: valor=%d, tamanho=%d bytes\n", b, unsafe.Sizeof(b))
fmt.Printf("uint8: valor=%d, tamanho=%d bytes\n", c, unsafe.Sizeof(c))
// Operações básicas
soma := a + 10
diferenca := a - 5
produto := a * 2
quociente := a / 3
resto := a % 3
fmt.Printf("Soma: %d, Diferença: %d, Produto: %d, Quociente: %d, Resto: %d\n",
soma, diferenca, produto, quociente, resto)
}
3. Tipos de ponto flutuante (float)
Go oferece dois tipos para números de ponto flutuante: float32 e float64. O float32 ocupa 4 bytes e oferece aproximadamente 7 dígitos decimais de precisão, enquanto o float64 ocupa 8 bytes e oferece aproximadamente 15 dígitos decimais.
package main
import (
"fmt"
"math"
)
func main() {
var precisaoSimples float32 = 1.0 / 3.0
var precisaoDupla float64 = 1.0 / 3.0
fmt.Printf("float32: %.20f\n", precisaoSimples)
fmt.Printf("float64: %.20f\n", precisaoDupla)
// Operações aritméticas
area := math.Pi * math.Pow(2.5, 2)
fmt.Printf("Área do círculo (raio=2.5): %.2f\n", area)
// Cuidado com arredondamento
resultado := 0.1 + 0.2
fmt.Printf("0.1 + 0.2 = %.20f\n", resultado) // Pequena imprecisão
}
4. Tipo string
Em Go, strings são sequências imutáveis de bytes. Elas podem ser declaradas com aspas duplas ou com crases para strings brutas (raw strings).
package main
import (
"fmt"
)
func main() {
// Strings com aspas duplas (interpretam escapes)
nome := "Golang"
saudacao := "Olá, " + nome + "!"
// Raw strings com crases (não interpretam escapes)
caminho := `C:\Users\Documents\go\projetos`
textoMultilinha := `Linha 1
Linha 2
Linha 3`
fmt.Println(saudacao)
fmt.Println(caminho)
fmt.Println(textoMultilinha)
// Indexação e slicing
fmt.Printf("Primeiro caractere: %c\n", nome[0])
fmt.Printf("Último caractere: %c\n", nome[len(nome)-1])
fmt.Printf("Slice [1:4]: %s\n", nome[1:4])
// Comprimento
fmt.Printf("Tamanho da string: %d bytes\n", len(nome))
}
5. Tipo bool
O tipo booleano em Go pode assumir apenas dois valores: true ou false. É amplamente utilizado em condicionais e controle de fluxo.
package main
import (
"fmt"
)
func main() {
var ativo bool = true
var completo bool = false
// Operadores lógicos
e := ativo && completo // AND
ou := ativo || completo // OR
nao := !ativo // NOT
fmt.Printf("ativo && completo: %t\n", e)
fmt.Printf("ativo || completo: %t\n", ou)
fmt.Printf("!ativo: %t\n", nao)
// Uso em condicionais
idade := 18
podeVotar := idade >= 16
if podeVotar {
fmt.Println("Pode votar!")
}
// Comparações retornam bool
fmt.Printf("10 > 5: %t\n", 10 > 5)
fmt.Printf("3 == 3: %t\n", 3 == 3)
}
6. Zero values (valores padrão)
Uma característica única de Go é que todas as variáveis são automaticamente inicializadas com seu zero value, eliminando a possibilidade de variáveis não inicializadas.
package main
import (
"fmt"
)
func main() {
var numeroInt int
var numeroFloat float64
var texto string
var flag bool
fmt.Printf("int: %d\n", numeroInt) // 0
fmt.Printf("float64: %f\n", numeroFloat) // 0.000000
fmt.Printf("string: '%s'\n", texto) // ""
fmt.Printf("bool: %t\n", flag) // false
// Implicações práticas
var contador int
contador++ // Seguro, pois contador já é 0
fmt.Printf("Contador: %d\n", contador)
var mensagem string
if mensagem == "" {
fmt.Println("Mensagem vazia - zero value útil para validação")
}
}
7. Conversão entre tipos
Go exige conversão explícita entre tipos diferentes, não permitindo conversões implícitas que poderiam causar perda de dados.
package main
import (
"fmt"
)
func main() {
// Conversão int para float
var idade int = 25
var idadeFloat float64 = float64(idade)
fmt.Printf("int para float: %f\n", idadeFloat)
// Conversão float para int (perde parte decimal)
var preco float64 = 29.99
var precoInt int = int(preco)
fmt.Printf("float para int: %d (perdeu .99)\n", precoInt)
// Conversão entre tipos inteiros (cuidado com overflow)
var grande int64 = 1000
var pequeno int8 = int8(grande) // Perigoso se valor exceder limite
fmt.Printf("int64 para int8: %d\n", pequeno)
// String para slice de bytes
palavra := "Go"
bytes := []byte(palavra)
fmt.Printf("Bytes: %v\n", bytes)
// Slice de bytes para string
original := string(bytes)
fmt.Printf("Original: %s\n", original)
}
8. Boas práticas e exemplos práticos
Ao trabalhar com tipos básicos em Go, algumas práticas são recomendadas:
- Prefira
intefloat64para uso geral, a menos que precise de tipos específicos por economia de memória - Use
uintapenas quando necessário (como para índices de slices) - Evite conversões desnecessárias que possam causar perda de precisão
- Utilize
fmt.Printfcom verbos adequados para formatação
package main
import (
"fmt"
)
func main() {
// Exemplo completo combinando todos os tipos básicos
nome := "Maria Silva"
idade := 30
altura := 1.75
estudante := false
// Usando fmt.Printf com verbos de formatação
fmt.Printf("Nome: %s\n", nome) // %s para string
fmt.Printf("Idade: %d anos\n", idade) // %d para inteiro
fmt.Printf("Altura: %.2f m\n", altura) // %f para float
fmt.Printf("Estudante: %t\n", estudante) // %t para bool
// Cálculo de IMC (Índice de Massa Corporal)
peso := 68.5
imc := peso / (altura * altura)
fmt.Printf("IMC: %.1f\n", imc)
// Validação de dados
if idade >= 18 && !estudante {
fmt.Printf("%s é maior de idade e não é estudante\n", nome)
}
// Uso de zero values para inicialização segura
var (
totalVendas float64
totalItens int
)
totalVendas += 150.50
totalItens++
totalVendas += 89.99
totalItens++
mediaVenda := totalVendas / float64(totalItens)
fmt.Printf("Total vendas: R$ %.2f, Média por item: R$ %.2f\n",
totalVendas, mediaVenda)
}
Referências
- Documentação oficial: Tipos básicos em Go — Especificação completa dos tipos da linguagem Go
- Tour of Go: Tipos básicos — Tutorial interativo oficial sobre tipos básicos em Go
- Go by Example: Values — Exemplos práticos de tipos básicos e zero values
- Effective Go: Inicialização — Boas práticas de inicialização e zero values em Go
- DigitalOcean: Understanding Data Types in Go — Guia detalhado sobre tipos de dados em Go
- GeeksforGeeks: Zero Value in Golang — Explicação completa sobre zero values em Go