Menu

Da int a stringa e da stringa a int in Golang: conversione di tipo

Come convertire tra tipi in Go: da int a stringa e da stringa a int con strconv, da float a int, conversioni numeriche con T(v), byte e rune, la trappola di string(65) e la gestione degli errori di conversione.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

Go non converte mai i tipi in modo implicito. Converti tra tipi compatibili con T(v), e tra numeri e testo con il pacchetto strconv. Le due conversioni più cercate:

strconv.Itoa ("integer to ASCII") formatta un int come testo decimale. strconv.Atoi ("ASCII to integer") interpreta un testo come int e restituisce un errore quando il testo non è un numero valido. Controlla sempre quell'errore.

La conversione T(v)

La sintassi di conversione di Go sembra una chiamata di funzione con il nome del tipo di destinazione. Funziona in tre situazioni:

  1. tra tipi numerici (int, int64, float64, uint8, ...),
  2. tra string e []byte o []rune,
  3. tra tipi che condividono lo stesso tipo sottostante (Celsius e float64).

Guarda bene i risultati:

  • int(3.9) è 3 e int(-3.9) è -3. La conversione tronca verso lo zero; non arrotonda. Usa prima math.Round, math.Floor o math.Ceil per scegliere il comportamento. math.Round arrotonda le metà allontanandosi dallo zero, quindi -3.5 diventa -4.
  • uint8(300) è 44, perché sopravvivono solo gli 8 bit bassi (300 meno 256), e int8(200) è -56 per lo stesso motivo. Nessun errore, nessun panic.
  • Celsius e float64 condividono il tipo sottostante, quindi si convertono liberamente, ma solo in modo esplicito.

I valori stanno in variabili di proposito. Con le costanti, le stesse conversioni non compilano.

Le costanti vengono controllate, le variabili no

Convertire una costante che non ci sta è un errore di compilazione. Convertire una variabile con lo stesso valore fa un wrap-around silenzioso:

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

Anche convertire una costante non intera in un tipo intero viene rifiutato, mentre lo stesso valore in una variabile viene troncato:

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

Se il valore float è fuori dall'intervallo del tipo intero di destinazione (per esempio int64(1e20)), il risultato dipende dall'implementazione: amd64 e arm64, per esempio, danno risposte diverse. Controlla l'intervallo prima di convertire valori non affidabili.

Convertire numeri in stringhe

DaFunzioneEsempioRisultato
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"
qualsiasi cosafmt.Sprint(v)fmt.Sprint(3.5)"3.5"
qualsiasi cosa, formattatafmt.Sprintf(format, v)fmt.Sprintf("%05d", 42)"00042"

FormatFloat accetta un byte di formato ('f' per la notazione fissa, 'e' per quella esponenziale, 'g' per la più breve delle due), una precisione (-1 significa "il minor numero di cifre che permette di tornare esattamente al valore") e la dimensione in bit del float originale (64 o 32).

strconv è più veloce di fmt.Sprint, che racchiude il valore in un'interfaccia e passa per il percorso di formattazione generico di fmt. In un ciclo critico la differenza si nota; per conversioni occasionali, scegli quella che si legge meglio.

Convertire stringhe in numeri

InFunzioneRestituisce
intstrconv.Atoi(s)int, error
qualsiasi intero con segnostrconv.ParseInt(s, base, bitSize)int64, error
qualsiasi intero senza segnostrconv.ParseUint(s, base, bitSize)uint64, error
floatstrconv.ParseFloat(s, bitSize)float64, error
boolstrconv.ParseBool(s)bool, error

ParseInt restituisce sempre un int64. L'argomento bitSize (0, 8, 16, 32, 64) stabilisce l'intervallo accettato, quindi il risultato è garantito entrare nel tipo più piccolo quando lo converti. base 0 significa "deduci dal prefisso", quindi 0x1f, 0o17, 0b101 e 1_000 vengono tutti interpretati.

Cosa mostra l'output:

  • " 42" fallisce. Atoi accetta un segno facoltativo e delle cifre, nient'altro. L'input letto con bufio di solito termina con \n, quindi rimuovilo.
  • "4.2" non è valido per Atoi. Usa ParseFloat per i decimali.
  • In caso di errore di intervallo, ParseInt restituisce il valore più grande che ci sta (127 per int8) insieme all'errore. Non usare il valore quando l'errore non è nil.
  • Gli errori sono valori *strconv.NumError che incapsulano strconv.ErrSyntax o strconv.ErrRange, quindi errors.Is può distinguerli.

ParseBool accetta 1, t, T, TRUE, true, True e le forme corrispondenti per false. "yes" e "on" sono errori.

La trappola di string(65)

Convertire un intero in string non produce cifre. Produce il carattere con quel code point Unicode:

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

Il compilatore lo accetta, ma go vet lo segnala:

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

Se vuoi davvero il carattere, dillo con una rune: string(rune(n)). Se vuoi il numero come testo, usa strconv.Itoa(n). Convertire una rune o un byte in string va bene ed è comune:

Stringhe, byte e rune

string, []byte e []rune si convertono l'uno nell'altro con T(v). Ogni conversione copia i dati, perché le stringhe sono immutabili e gli slice no:

Converti in []rune quando devi indicizzare o modificare per carattere; converti in []byte per I/O, hashing e modifiche a livello di byte. La pagina su rune e byte tratta UTF-8 in dettaglio.

Conversione e type assertion

Una conversione trasforma un valore da un tipo concreto a un altro. Estrarre il valore concreto da un'interfaccia (any, error, io.Reader) è un'operazione diversa, la 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

Prima asserisci, poi converti. La forma comma-ok n, ok := v.(int) evita un panic quando il tipo è sbagliato.

Riferimento rapido

OperazioneCodice
da int a stringastrconv.Itoa(n)
da int64 a stringastrconv.FormatInt(n, 10)
da stringa a intn, err := strconv.Atoi(s)
da stringa a int64n, err := strconv.ParseInt(s, 10, 64)
da stringa a float64f, err := strconv.ParseFloat(s, 64)
da float64 a stringastrconv.FormatFloat(f, 'f', -1, 64)
da float64 a intint(f) (tronca) oppure int(math.Round(f))
da int a float64float64(n)
da stringa a []byte[]byte(s)
da []byte a stringastring(b)
da rune a stringastring(r)
da bool a stringastrconv.FormatBool(b)
da qualsiasi valore a stringafmt.Sprint(v)

Domande frequenti

Come converto un int in stringa in Go?

Usa strconv.Itoa(n): strconv.Itoa(42) restituisce "42". Per un int64 usa strconv.FormatInt(n, 10). Anche fmt.Sprint(n) funziona con qualsiasi tipo, ma è più lento. Non scrivere string(n): tratta n come un code point Unicode, quindi string(65) è "A".

Come converto una stringa in int in Go?

Usa strconv.Atoi, che restituisce il numero e un errore:

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

Per una dimensione o una base specifica usa strconv.ParseInt(s, 10, 64), che restituisce un int64. Atoi non rimuove gli spazi, quindi " 42" è un errore; chiama prima strings.TrimSpace.

Come si fa un cast in Go?

Go la chiama conversione, e la sintassi è T(v): float64(n), int(f), []byte(s). Funziona tra tipi numerici, tra stringhe e slice di byte o di rune, e tra tipi con lo stesso tipo sottostante. Non interpreta il testo: trasformare "42" in 42 richiede strconv. Estrarre un tipo concreto da un'interfaccia è una type assertion, v.(T), non una conversione.

Come converto un float in int in Go?

int(f) tronca verso lo zero: int(3.9) è 3 e int(-3.9) è -3. Per arrotondare usa int(math.Round(f)). Se il float è fuori dall'intervallo del tipo intero il risultato dipende dall'implementazione, quindi controlla prima l'intervallo quando il valore arriva da un input.

Perché string(65) restituisce "A" in Go?

Convertire un intero in string lo interpreta come un code point Unicode, e 65 è il code point di A. go vet lo segnala: conversion from int to string yields a string of one rune, not a string of digits. Usa strconv.Itoa(65) per ottenere "65".

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA