00
:
00
:
00
:
00
•Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

Conversione di Tipi in Go

In Go, le conversioni di tipo sono sempre esplicite. A differenza di altri linguaggi, Go non esegue conversioni implicite tra tipi, nemmeno tra tipi numerici compatibili. Questa scelta rende il codice piu sicuro e prevedibile.

Conversione Esplicita T(v)

La sintassi base per convertire un valore v al tipo T e T(v):

package main

import "fmt"

func main() {
    var intero int = 42
    var decimale float64 = float64(intero) // int -> float64
    var piccolo int32 = int32(intero)      // int -> int32

    fmt.Println(intero)    // 42
    fmt.Println(decimale)  // 42
    fmt.Println(piccolo)   // 42
}

Senza la conversione esplicita, Go genera un errore di compilazione:

var a int = 10
var b float64 = a // ERRORE: cannot use a (variable of type int) as float64

Conversioni tra Tipi Numerici

Int e Float

func main() {
    // Da int a float
    i := 42
    f := float64(i)
    fmt.Println(f) // 42

    // Da float a int (troncamento, non arrotondamento)
    pi := 3.99
    n := int(pi)
    fmt.Println(n) // 3 (la parte decimale viene troncata)

    // Attenzione al troncamento
    negativo := -2.7
    fmt.Println(int(negativo)) // -2
}

Tra Diversi Tipi Interi

func main() {
    var grande int64 = 1000
    var piccolo int8 = int8(grande)
    fmt.Println(piccolo) // -24 (overflow! 1000 non entra in int8)

    var senza uint = 42
    var con int = int(senza)
    fmt.Println(con) // 42
}

Attenzione: le conversioni tra tipi numerici possono causare perdita di dati o overflow. Go non segnala errori in questi casi.

Float32 e Float64

func main() {
    var f64 float64 = 3.141592653589793
    var f32 float32 = float32(f64)

    fmt.Printf("float64: %.15f\n", f64) // 3.141592653589793
    fmt.Printf("float32: %.15f\n", f32) // 3.141592741012573 (perdita di precisione)
}

Conversione Stringa - Numero con strconv

Il pacchetto strconv fornisce funzioni per convertire tra stringhe e tipi numerici.

String a Int: strconv.Atoi

package main

import (
    "fmt"
    "strconv"
)

func main() {
    s := "42"
    n, err := strconv.Atoi(s)
    if err != nil {
        fmt.Println("Errore:", err)
        return
    }
    fmt.Println(n) // 42

    // Errore con stringa non valida
    _, err = strconv.Atoi("abc")
    fmt.Println(err) // strconv.Atoi: parsing "abc": invalid syntax
}

Int a String: strconv.Itoa

func main() {
    n := 42
    s := strconv.Itoa(n)
    fmt.Println(s)         // "42"
    fmt.Printf("%T\n", s)  // string
}

Conversioni con ParseInt e ParseFloat

Per maggiore controllo si usano ParseInt e ParseFloat:

func main() {
    // ParseInt con base e dimensione
    n, err := strconv.ParseInt("FF", 16, 64) // esadecimale, 64 bit
    fmt.Println(n, err) // 255 <nil>

    // ParseFloat
    f, err := strconv.ParseFloat("3.14", 64)
    fmt.Println(f, err) // 3.14 <nil>

    // ParseBool
    b, err := strconv.ParseBool("true")
    fmt.Println(b, err) // true <nil>
}

Formattazione con FormatInt e FormatFloat

func main() {
    // FormatInt: converte int in stringa con base
    s := strconv.FormatInt(255, 16)
    fmt.Println(s) // "ff"

    // FormatFloat: converte float in stringa con formato
    sf := strconv.FormatFloat(3.14159, 'f', 2, 64)
    fmt.Println(sf) // "3.14"
}

Conversione Byte Slice e Stringa

La conversione tra []byte e string e molto comune in Go:

Da String a []byte

func main() {
    s := "Ciao, Go!"
    b := []byte(s)
    fmt.Println(b) // [67 105 97 111 44 32 71 111 33]

    // Modifica dei byte
    b[0] = 'M' // modifica il primo byte
    fmt.Println(string(b)) // "Miao, Go!"
}

Da []byte a String

func main() {
    b := []byte{72, 101, 108, 108, 111}
    s := string(b)
    fmt.Println(s) // "Hello"
}

Rune e Stringhe

Le rune (rune e un alias per int32) rappresentano un singolo carattere Unicode:

func main() {
    s := "Ciao"

    // String a []rune
    rune_slice := []rune(s)
    fmt.Println(rune_slice) // [67 105 97 111]

    // Singola rune a string
    r := rune('A')
    fmt.Println(string(r)) // "A"

    // Intero a string (restituisce il carattere Unicode)
    fmt.Println(string(65)) // "A"
    fmt.Println(string(8364)) // carattere euro
}

Type Assertion vs Type Conversion

E importante distinguere tra type assertion e type conversion:

Type Conversion

Converte un valore da un tipo concreto a un altro tipo concreto:

var i int = 42
var f float64 = float64(i) // type conversion

Type Assertion

Estrae il tipo concreto da un’interfaccia:

var i interface{} = "ciao"

// Type assertion sicura (con controllo)
s, ok := i.(string)
if ok {
    fmt.Println("E una stringa:", s)
}

// Type assertion non sicura (panic se il tipo non corrisponde)
s2 := i.(string) // OK
// n := i.(int)   // PANIC: interface conversion: string, not int

Type Switch

Per controllare piu tipi possibili:

func descrivi(valore interface{}) string {
    switch v := valore.(type) {
    case int:
        return fmt.Sprintf("Intero: %d", v)
    case string:
        return fmt.Sprintf("Stringa: %s", v)
    case float64:
        return fmt.Sprintf("Float: %.2f", v)
    case bool:
        return fmt.Sprintf("Booleano: %t", v)
    default:
        return fmt.Sprintf("Tipo sconosciuto: %T", v)
    }
}

func main() {
    fmt.Println(descrivi(42))       // Intero: 42
    fmt.Println(descrivi("ciao"))   // Stringa: ciao
    fmt.Println(descrivi(3.14))     // Float: 3.14
    fmt.Println(descrivi(true))     // Booleano: true
}

Conversione con fmt.Sprintf

fmt.Sprintf puo essere usato come conversione “universale” verso stringa:

func main() {
    n := 42
    f := 3.14
    b := true

    s1 := fmt.Sprintf("%d", n)  // "42"
    s2 := fmt.Sprintf("%.2f", f) // "3.14"
    s3 := fmt.Sprintf("%t", b)  // "true"

    fmt.Println(s1, s2, s3)
}

Conclusione

La conversione esplicita dei tipi in Go previene errori silenziosi e rende il codice piu chiaro. Il pacchetto strconv e lo strumento principale per le conversioni tra stringhe e numeri, mentre la type assertion permette di estrarre tipi concreti dalle interfacce. Comprendere la differenza tra type conversion e type assertion, e le possibili perdite di dati nelle conversioni numeriche, e fondamentale per scrivere codice Go corretto e robusto.