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

Scope delle Variabili in Go

Lo scope (ambito di visibilità) di una variabile in Go determina dove quella variabile è accessibile nel codice. Comprendere lo scope è fondamentale per scrivere codice corretto e prevedibile.

Scope a Livello di Pacchetto

Le variabili dichiarate fuori da qualsiasi funzione sono accessibili in tutto il pacchetto:

package main

var contatore int = 0 // Visibile in tutto il pacchetto

func incrementa() {
    contatore++ // Accede alla variabile di pacchetto
}

func main() {
    incrementa()
    fmt.Println(contatore) // 1
}

Se il nome inizia con lettera maiuscola, la variabile è esportata e accessibile anche da altri pacchetti.

Scope a Livello di Funzione

Le variabili dichiarate all’interno di una funzione sono visibili solo in quella funzione:

func main() {
    messaggio := "Ciao"
    fmt.Println(messaggio) // OK
}

func altraFunzione() {
    // fmt.Println(messaggio) // ERRORE: messaggio non è definita qui
}

Scope a Livello di Blocco

Ogni blocco {} crea un nuovo scope. Le variabili dichiarate in un blocco non sono visibili al di fuori:

func main() {
    x := 10

    if x > 5 {
        y := 20 // y è visibile solo in questo blocco if
        fmt.Println(x, y) // 10 20
    }

    // fmt.Println(y) // ERRORE: y non è definita qui

    for i := 0; i < 3; i++ {
        // i è visibile solo nel ciclo for
        fmt.Println(i)
    }
    // fmt.Println(i) // ERRORE: i non è definita qui
}

Scope con If e Inizializzazione

L’inizializzazione nell’if crea una variabile visibile solo nel blocco if-else:

if valore, err := strconv.Atoi("42"); err == nil {
    fmt.Println(valore) // 42 - visibile qui
} else {
    fmt.Println(err) // valore ed err visibili anche nell'else
}
// valore e err NON sono visibili qui

Shadowing (Oscuramento)

Una variabile in uno scope interno può “oscurare” una variabile con lo stesso nome in uno scope esterno:

func main() {
    x := 10
    fmt.Println(x) // 10

    {
        x := 20 // Nuova variabile x, oscura quella esterna
        fmt.Println(x) // 20
    }

    fmt.Println(x) // 10 - la x esterna non è cambiata
}

Attenzione: lo shadowing con := è una fonte comune di bug:

func main() {
    err := errors.New("errore iniziale")

    if true {
        // Crea una NUOVA variabile err, non modifica quella esterna
        valore, err := qualcosa()
        fmt.Println(valore, err)
    }

    fmt.Println(err) // Ancora "errore iniziale"!
}

Best Practice

  • Dichiara le variabili il piĂą vicino possibile al loro utilizzo
  • Fai attenzione allo shadowing involontario con :=
  • Limita lo scope delle variabili al minimo necessario
  • Usa nomi diversi se hai bisogno di accedere a variabili di scope diversi

Conclusione

Go utilizza lo scope lessicale con blocchi annidati. Ogni {} crea un nuovo scope, e le variabili sono visibili solo nel blocco in cui sono dichiarate e nei blocchi interni. Lo shadowing è una caratteristica potente ma può causare bug sottili se non gestita con attenzione.