Menu

Golang: int para string, string para int e conversão de tipos

Como converter entre tipos em Go: int para string e string para int com strconv, float para int, conversões numéricas com T(v), bytes e runes, a armadilha do string(65) e o tratamento de erros de conversão.

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

Go nunca converte tipos implicitamente. Você converte entre tipos compatíveis com T(v), e entre números e texto com o pacote strconv. As duas conversões mais buscadas:

strconv.Itoa ("integer to ASCII") formata um int como texto decimal. strconv.Atoi ("ASCII to integer") interpreta um texto como int e devolve um erro quando o texto não é um número válido. Sempre verifique esse erro.

A conversão T(v)

A sintaxe de conversão do Go parece uma chamada de função com o nome do tipo de destino. Ela funciona em três situações:

  1. entre tipos numéricos (int, int64, float64, uint8, ...),
  2. entre string e []byte ou []rune,
  3. entre tipos que compartilham o tipo subjacente (Celsius e float64).

Leia os resultados com atenção:

  • int(3.9) é 3 e int(-3.9) é -3. A conversão trunca em direção a zero; ela não arredonda. Use antes math.Round, math.Floor ou math.Ceil para escolher o comportamento. math.Round arredonda a metade para longe do zero, então -3.5 vira -4.
  • uint8(300) é 44, porque só sobram os 8 bits mais baixos (300 menos 256), e int8(200) é -56 pelo mesmo motivo. Sem erro, sem panic.
  • Celsius e float64 compartilham o tipo subjacente, então convertem livremente, mas só de forma explícita.

Os valores estão em variáveis de propósito. Com constantes, as mesmas conversões não compilam.

Constantes são verificadas, variáveis não

Converter uma constante que não cabe no tipo é erro de compilação. Converter uma variável com o mesmo valor dá a volta em silêncio:

fmt.Println(uint8(300)) // compile error
x := 300
fmt.Println(uint8(x)) // 44
./main.go:6:20: constant 300 overflows uint8

Converter uma constante não inteira para um tipo inteiro também é rejeitado, enquanto o mesmo valor em uma variável é truncado:

./main.go:7:18: cannot convert -3.9 (untyped float constant) to type int

Se o valor float estiver fora da faixa do tipo inteiro de destino (por exemplo int64(1e20)), o resultado depende da implementação: amd64 e arm64, por exemplo, dão respostas diferentes. Confira a faixa antes de converter valores não confiáveis.

Convertendo números em strings

DeFunçãoExemploResultado
intstrconv.Itoa(n)strconv.Itoa(-7)"-7"
int64strconv.FormatInt(n, base)strconv.FormatInt(255, 16)"ff"
uint64strconv.FormatUint(n, base)strconv.FormatUint(5, 2)"101"
float64strconv.FormatFloat(f, fmt, prec, 64)strconv.FormatFloat(3.14159, 'f', 2, 64)"3.14"
boolstrconv.FormatBool(b)strconv.FormatBool(true)"true"
qualquer coisafmt.Sprint(v)fmt.Sprint(3.5)"3.5"
qualquer coisa, formatadafmt.Sprintf(format, v)fmt.Sprintf("%05d", 42)"00042"

FormatFloat recebe um byte de formato ('f' para notação fixa, 'e' para expoente, 'g' para o que for mais curto), uma precisão (-1 significa "o menor número de dígitos que volta exatamente ao mesmo valor") e o tamanho em bits do float original (64 ou 32).

strconv é mais rápido que fmt.Sprint, que empacota o valor em uma interface e passa pelo caminho de formatação genérico do fmt. Em um laço quente essa diferença aparece; para conversões ocasionais, escolha o que for mais legível.

Convertendo strings em números

ParaFunçãoDevolve
intstrconv.Atoi(s)int, error
qualquer int com sinalstrconv.ParseInt(s, base, bitSize)int64, error
qualquer int sem sinalstrconv.ParseUint(s, base, bitSize)uint64, error
floatstrconv.ParseFloat(s, bitSize)float64, error
boolstrconv.ParseBool(s)bool, error

ParseInt sempre devolve um int64. O argumento bitSize (0, 8, 16, 32, 64) define a faixa aceita, então o resultado com certeza cabe quando você o converte para um tipo menor. base 0 significa "deduzir pelo prefixo", então 0x1f, 0o17, 0b101 e 1_000 são todos aceitos.

O que a saída mostra:

  • " 42" falha. O Atoi aceita um sinal opcional e dígitos, nada mais. Entradas lidas com bufio costumam terminar em \n, então remova isso.
  • "4.2" é inválido para o Atoi. Use ParseFloat para decimais.
  • Em um erro de faixa, ParseInt devolve o maior valor que cabe (127 para int8) junto com o erro. Não use o valor quando o erro não for nil.
  • Os erros são valores *strconv.NumError que empacotam strconv.ErrSyntax ou strconv.ErrRange, então errors.Is consegue diferenciá-los.

ParseBool aceita 1, t, T, TRUE, true, True e as formas equivalentes de false. "yes" e "on" dão erro.

A armadilha do string(65)

Converter um inteiro para string não gera dígitos. Gera o caractere com aquele code point Unicode:

n := 65
s := string(n) // "A", not "65"

O compilador aceita, mas o go vet reporta:

./main.go:10:7: conversion from int to string yields a string of one rune, not a string of digits

Se você quer mesmo o caractere, deixe isso claro com uma rune: string(rune(n)). Se quer o número como texto, use strconv.Itoa(n). Converter uma rune ou um byte para string é normal e comum:

Strings, bytes e runes

string, []byte e []rune se convertem entre si com T(v). Cada conversão copia os dados, porque strings são imutáveis e slices não:

Converta para []rune quando precisar indexar ou modificar por caractere; converta para []byte para I/O, hashing e edições no nível de byte. A página de runes e bytes explica o UTF-8 em detalhes.

Conversão ou type assertion

Uma conversão muda um valor de um tipo concreto para outro. Tirar o valor concreto de dentro de uma interface (any, error, io.Reader) é outra operação, a type assertion:

var v any = 42

n := v.(int)       // type assertion: v holds an int, give it to me
f := float64(n)    // conversion: int to float64
// f := float64(v) // compile error: cannot convert v (variable of interface type any)
//                  // to type float64: need type assertion

Primeiro a assertion, depois a conversão. A forma vírgula-ok n, ok := v.(int) evita um panic quando o tipo está errado.

Referência rápida

TarefaCódigo
int para stringstrconv.Itoa(n)
int64 para stringstrconv.FormatInt(n, 10)
string para intn, err := strconv.Atoi(s)
string para int64n, err := strconv.ParseInt(s, 10, 64)
string para float64f, err := strconv.ParseFloat(s, 64)
float64 para stringstrconv.FormatFloat(f, 'f', -1, 64)
float64 para intint(f) (trunca) ou int(math.Round(f))
int para float64float64(n)
string para []byte[]byte(s)
[]byte para stringstring(b)
rune para stringstring(r)
bool para stringstrconv.FormatBool(b)
qualquer valor para stringfmt.Sprint(v)

Perguntas frequentes

Como converter um int para string em Go?

Use strconv.Itoa(n): strconv.Itoa(42) devolve "42". Para um int64 use strconv.FormatInt(n, 10). fmt.Sprint(n) também funciona com qualquer tipo, mas é mais lento. Não escreva string(n): isso trata n como um code point Unicode, então string(65) é "A".

Como converter uma string para int em Go?

Use strconv.Atoi, que devolve o número e um erro:

n, err := strconv.Atoi("42")
if err != nil {
	// not a valid integer
}

Para um tamanho ou uma base específicos, use strconv.ParseInt(s, 10, 64), que devolve um int64. O Atoi não remove espaços, então " 42" dá erro; chame strings.TrimSpace antes.

Como fazer cast em Go?

Go chama isso de conversão, e a sintaxe é T(v): float64(n), int(f), []byte(s). Funciona entre tipos numéricos, entre strings e slices de bytes ou de runes, e entre tipos com o mesmo tipo subjacente. Ela não interpreta texto: transformar "42" em 42 exige strconv. Tirar um tipo concreto de dentro de uma interface é uma type assertion, v.(T), não uma conversão.

Como converter um float para int em Go?

int(f) trunca em direção a zero: int(3.9) é 3 e int(-3.9) é -3. Para arredondar, use int(math.Round(f)). Se o float estiver fora da faixa do tipo inteiro, o resultado depende da implementação, então confira a faixa antes quando o valor vier de uma entrada externa.

Por que string(65) devolve "A" em Go?

Converter um inteiro para string o interpreta como um code point Unicode, e 65 é o code point de A. O go vet aponta isso: conversion from int to string yields a string of one rune, not a string of digits. Use strconv.Itoa(65) para obter "65".

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR