Tipos básicos
Esta aula aborda os tipos básicos da linguagem Go: inteiros, floats, strings, runes e booleanos, além de conversões explícitas entre tipos. O conteúdo inclui exemplos práticos, boas práticas e exercícios com respostas colapsáveis para fixação.
Em Go, os tipos básicos formam a base para toda a manipulação de dados. Eles incluem números inteiros e de ponto flutuante, strings e runes para texto, e booleanos para lógica. Entender esses tipos e como convertê-los explicitamente é essencial para escrever código correto e eficiente.
Diferente de algumas linguagens, Go é fortemente tipada e não realiza conversões implícitas entre tipos. Isso evita bugs sutis, mas exige que o programador seja explícito nas transformações. Vamos explorar cada um desses tipos com exemplos práticos.
Inteiros e floats
Go oferece vários tamanhos de inteiros com e sem sinal: int8, int16, int32, int64, uint8, uint16, uint32, uint64. Além disso, int e uint têm tamanho dependente da plataforma (32 ou 64 bits). Para números de ponto flutuante, temos float32 e float64 (e complex64/complex128 para números complexos).
Exemplo de declaração e uso:
package main
import "fmt"
func main() {
var a int = 10
var b int8 = 20
var c int64 = 30
var d uint = 40
var e float32 = 3.14
var f float64 = 2.71828
fmt.Println(a, b, c, d, e, f)
}É importante notar que você não pode misturar tipos diferentes em expressões sem conversão explícita. Por exemplo, a + b causará um erro de compilação porque a é int e b é int8.
Strings e runes
Em Go, strings são sequências imutáveis de bytes (UTF-8). Elas são declaradas com aspas duplas. Runes representam um único caractere Unicode e são do tipo rune (que é um alias para int32). Runes são declaradas com aspas simples.
Exemplo:
package main
import "fmt"
func main() {
var s string = "Olá, mundo!"
var r rune = 'O'
fmt.Println(s, r)
// Acessando bytes e runes
for i, c := range s {
fmt.Printf("byte %d: %c (rune %d)\n", i, c, c)
}
}Strings podem ser concatenadas com + e comparadas com ==. Runes são úteis para trabalhar com caracteres Unicode de forma individual.
Booleanos
O tipo booleano em Go é bool e pode ser true ou false. Operadores lógicos como &&, || e ! são usados para combinar valores booleanos.
Exemplo:
package main
import "fmt"
func main() {
var ativo bool = true
var ok bool = false
if ativo && !ok {
fmt.Println("Ativo e não ok")
}
}Go não permite conversão implícita de booleanos para inteiros ou vice-versa. Você deve usar explicitamente uma condição.
Conversões explícitas
Para converter entre tipos numéricos, use a sintaxe T(v), onde T é o tipo de destino e v é o valor. Para strings e runes, há funções como string() e []rune(). Conversões podem perder precisão ou causar overflow, então tome cuidado.
Exemplos:
package main
import "fmt"
func main() {
var x int = 42
var f float64 = float64(x) // 42.0
var u uint = uint(f) // 42
var s string = string(rune(65)) // "A"
fmt.Println(x, f, u, s)
// Conversão de string para slice de bytes
b := []byte("Hello")
fmt.Println(b)
}Lembre-se: conversões entre tipos não relacionados (como int para string) podem não fazer o que você espera. Sempre verifique a documentação.
Boas práticas
Prefira usar tipos com tamanho explícito quando a portabilidade for importante (ex.: int64 para IDs). Use float64 para cálculos de precisão dupla. Evite conversões desnecessárias e sempre trate possíveis perdas de dados. Para strings, lembre-se de que a iteração com range retorna runes, não bytes.
Referências
- Go Specification: Types
- Numeric types
- String types
- Boolean types
- Conversions
- Go Blog: Strings, bytes, runes and characters
Exercícios
- Declare uma variável
idadecomointe atribua 25. Depois converta parafloat64e imprima. - Escreva um programa que declare uma string
nomecom seu nome e imprima o número de runes (caracteres Unicode) que ela contém. - Crie uma variável booleana
chovendoe atribuatrue. Use uma estrutura condicional para imprimir "Leve guarda-chuva" se for verdadeiro. - Converta um inteiro
65para string e imprima o resultado. Explique o que acontece. - Escreva um programa que converta um
float64parainte observe a perda de precisão.
package main
import "fmt"
func main() {
var idade int = 25
var f float64 = float64(idade)
fmt.Println(f)
}package main
import "fmt"
func main() {
nome := "João"
runes := []rune(nome)
fmt.Println(len(runes))
}package main
import "fmt"
func main() {
chovendo := true
if chovendo {
fmt.Println("Leve guarda-chuva")
}
}package main
import "fmt"
func main() {
var n int = 65
s := string(rune(n))
fmt.Println(s) // Imprime "A"
}A conversão de um inteiro para string usando string(rune(n)) interpreta o inteiro como um ponto de código Unicode e retorna a string correspondente. 65 é o código de 'A'.
package main
import "fmt"
func main() {
var pi float64 = 3.14159
var i int = int(pi)
fmt.Println(i) // Imprime 3, truncado
}