Menu

Tipos de dados em Golang: int, float64, string, bool, byte, rune

Os tipos embutidos do Go: tamanhos e faixas dos inteiros, float32 e float64, bool, string, byte e rune, números complexos, valores zero e como imprimir o tipo de um valor com %T.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

Os tipos básicos do Go são números, booleanos e strings. Toda variável tem exatamente um tipo, fixado em tempo de compilação, e o Go nunca converte entre tipos por você. %T imprime o tipo de qualquer valor:

Repare que 'G' é impresso como 71, com tipo int32: um caractere entre aspas simples é uma rune, que é um número (o code point Unicode). rune é um alias de int32 (o mesmo tipo com um segundo nome), então %T mostra int32. Do mesmo jeito, byte aparece como uint8.

Inteiros

TipoTamanhoFaixa
int88 bits-128 a 127
int1616 bits-32.768 a 32.767
int3232 bitscerca de -2,1 bilhões a 2,1 bilhões
int6464 bitscerca de -9,2 quintilhões a 9,2 quintilhões
uint8 (byte)8 bits0 a 255
uint1616 bits0 a 65.535
uint3232 bits0 a cerca de 4,3 bilhões
uint6464 bits0 a cerca de 18,4 quintilhões
int, uint32 ou 64 bitstamanho da palavra da plataforma
uintptrtamanho da plataformaguarda o valor de um ponteiro, para código de baixo nível

Use int por padrão. len() devolve int, índices de slice são int e contadores de laço são int. Em toda plataforma de 64 bits, int tem 64 bits. Recorra aos tipos com tamanho quando o tamanho fizer parte de um contrato: int32 em um formato de arquivo binário, uint8 para bytes brutos, int64 para um timestamp Unix em nanossegundos.

Evite tipos sem sinal para quantidades que "não podem ser negativas", como contagens. Subtrair além de zero dá a volta para um número enorme, em vez de gerar um negativo que você conseguiria detectar.

Limites e overflow

O pacote math tem uma constante para cada limite. Em tempo de execução, uma conta inteira que estoura dá a volta em silêncio:

Sem panic, sem erro: 127 + 1 vira -128. Só expressões constantes são verificadas em tempo de compilação (var b int8 = 128 não compila). Se overflow for possível com os seus dados, verifique antes da operação ou use math/big.

Literais inteiros

million := 1_000_000   // underscores for readability (Go 1.13+)
mask := 0xFF           // hexadecimal
perm := 0o755          // octal (also the older form 0755)
flags := 0b1010        // binary

Números de ponto flutuante

TipoTamanhoPrecisão
float3232 bitscerca de 6 a 9 dígitos significativos
float6464 bitscerca de 15 a 17 dígitos significativos

Um literal com ponto decimal ou expoente (2.5, 1e6) é float64 por padrão, e o pacote math recebe e devolve float64. Use esse tipo, a menos que a memória de um array grande importe.

Floats são binários, então a maioria das frações decimais é uma aproximação:

Daí saem duas regras. Nunca compare floats com == depois de fazer contas. E nunca guarde dinheiro em float: use um número inteiro de centavos ou uma biblioteca decimal.

Dividir um float por zero dá +Inf, -Inf ou NaN em vez de panic. Dividir um inteiro por zero causa panic em tempo de execução (runtime error: integer divide by zero), e um divisor zero constante é erro de compilação.

Booleanos

bool guarda true ou false, e o valor zero é false. Go não trata números, strings vazias ou nil como booleanos. if count {} é erro de compilação; escreva if count > 0 {}. Os operadores são &&, || e !, e && e || fazem avaliação de curto-circuito.

Strings

Uma string é uma sequência imutável de bytes, normalmente texto UTF-8. len(s) conta bytes, não caracteres:

é ocupa dois bytes em UTF-8, então len mostra 6 para cinco caracteres. Strings entre aspas duplas processam escapes como \n; raw strings entre crases não processam, e podem ocupar várias linhas. A página de strings cobre o pacote strings, e a de runes e bytes aprofunda o UTF-8.

byte e rune

AliasMesmo queGuarda
byteuint8um byte de dado bruto
runeint32um code point Unicode

São aliases, não tipos novos: um byte e um uint8 são intercambiáveis sem conversão. Os nomes dizem o que o número significa.

Números complexos

Go tem tipos complexos embutidos, complex64 e complex128, com real, imag e o pacote math/cmplx:

Poucos programas precisam deles, mas processamento de sinais e parte do código numérico precisam.

Tipos compostos e de referência

Os tipos básicos se combinam em tipos compostos. Cada um tem a sua página:

TipoExemploValor zero
array[3]inttrês zeros
slice[]intnil
mapmap[string]intnil
structstruct{ X, Y int }todos os campos zerados
ponteiro*intnil
funçãofunc(int) intnil
channelchan intnil
interfaceerror, anynil

any é um alias de interface{} (desde o Go 1.18) e pode guardar um valor de qualquer tipo.

Tipos nomeados

Você pode definir um tipo novo a partir de um existente. Ele tem a mesma representação, mas é um tipo distinto, e pode ter métodos:

type Celsius float64
type UserID int64

var t Celsius = 21.5
var f float64 = t // compile error: cannot use t (variable of float64 type Celsius) as float64 value in variable declaration

Essa rigidez é proposital: um UserID não pode ser passado por acidente onde se espera um OrderID. Converta explicitamente quando for essa a intenção: float64(t). Veja conversão de tipos para as regras e as funções de strconv para ir de números para strings e vice-versa.

Valores zero

Todo tipo tem um valor zero, que é o que a variável guarda antes de você atribuir algo: 0 para números, false para bool, "" para strings e nil para ponteiros, slices, maps, channels, funções e interfaces. Não existem variáveis não inicializadas em Go.

Perguntas frequentes

Qual o tamanho de um int em Go?

int e uint têm 64 bits em plataformas de 64 bits (amd64, arm64) e 32 bits em plataformas de 32 bits. Se você precisa de um tamanho fixo, para um formato de arquivo ou protocolo de rede, use int32, int64, uint8 e assim por diante. Para contadores, índices e tamanhos comuns, use int.

Como imprimir o tipo de uma variável em Go?

Use o verbo %T: fmt.Printf("%T\n", x) imprime int, float64, []string, main.User e assim por diante. No código, reflect.TypeOf(x) devolve a mesma informação como um valor que você pode inspecionar.

Qual a diferença entre byte e rune em Go?

byte é um alias de uint8 e guarda um byte de dado bruto. rune é um alias de int32 e guarda um code point Unicode. Uma string é uma sequência de bytes; percorrê-la com for range a decodifica em runes.

Devo usar float32 ou float64 em Go?

Use float64, a menos que tenha um motivo para não usar. É o tipo padrão dos literais de ponto flutuante, o tipo com que o pacote math trabalha, e tem cerca de 15 a 17 dígitos decimais significativos de precisão, contra cerca de 6 a 9 do float32. Escolha float32 só para reduzir pela metade a memória de arrays grandes ou para bater com um formato externo.

Qual o valor máximo de um int em Go?

Use as constantes do pacote math: math.MaxInt (9223372036854775807 em plataformas de 64 bits), math.MinInt, math.MaxInt64, math.MaxUint32 e assim por diante. Uma conta que passa do limite dá a volta em silêncio em tempo de execução; ela não causa panic.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR