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

Costanti

Cosa sono le costanti?

Le costanti sono valori che non possono essere modificati dopo la loro dichiarazione. In Go, le costanti vengono definite con la parola chiave const e il loro valore deve essere noto al momento della compilazione.

package main

import "fmt"

const pi = 3.14159265358979

func main() {
    fmt.Println("Il valore di pi greco e:", pi)
    // pi = 3.14 // ERRORE: cannot assign to pi
}

Dichiarazione con const

Le costanti si dichiarano in modo simile alle variabili, ma con const al posto di var:

const nome string = "Go"
const versione = 1.23
const attivo = true

A differenza delle variabili, le costanti non possono essere dichiarate con :=:

// ERRORE: la sintassi breve non e disponibile per le costanti
// pi := 3.14  // questo dichiara una variabile, non una costante

Le costanti possono essere dichiarate sia a livello di pacchetto che all’interno di funzioni:

package main

import "fmt"

const messaggioGlobale = "Ciao dal livello pacchetto"

func main() {
    const messaggioLocale = "Ciao dal livello funzione"
    fmt.Println(messaggioGlobale)
    fmt.Println(messaggioLocale)
}

Costanti tipizzate e non tipizzate

Una delle caratteristiche piu potenti delle costanti in Go e la distinzione tra costanti tipizzate e non tipizzate.

Costanti tipizzate

Una costante tipizzata ha un tipo esplicito e si comporta esattamente come un valore di quel tipo:

const eta int = 30
const altezza float64 = 1.75
const nome string = "Mario"

Costanti non tipizzate

Una costante non tipizzata non ha un tipo fisso e puo essere usata in contesti diversi. Il tipo viene determinato dal contesto in cui la costante viene utilizzata:

const x = 42 // costante non tipizzata

func main() {
    var a int = x       // x diventa int
    var b float64 = x   // x diventa float64
    var c int64 = x     // x diventa int64

    fmt.Println(a, b, c) // 42 42 42
}

Questo comportamento e particolarmente utile per le costanti numeriche che devono essere flessibili:

const fattore = 1000

func main() {
    var piccolo int16 = fattore   // OK
    var grande int64 = fattore    // OK
    var decimale float64 = fattore // OK: diventa 1000.0

    fmt.Println(piccolo, grande, decimale)
}

Blocchi di costanti

Puoi raggruppare piu costanti in un blocco per migliorare la leggibilita:

const (
    linguaggio = "Go"
    versione   = "1.23"
    autore     = "Google"
)

const (
    secondiAlMinuto = 60
    minutiAllOra    = 60
    oreAlGiorno     = 24
    secondiAlGiorno = secondiAlMinuto * minutiAllOra * oreAlGiorno
)

Le costanti in un blocco possono fare riferimento a costanti precedenti e utilizzare espressioni:

package main

import "fmt"

const (
    kb = 1024
    mb = kb * 1024
    gb = mb * 1024
    tb = gb * 1024
)

func main() {
    fmt.Printf("1 KB = %d byte\n", kb)
    fmt.Printf("1 MB = %d byte\n", mb)
    fmt.Printf("1 GB = %d byte\n", gb)
    fmt.Printf("1 TB = %d byte\n", tb)
}

L’enumeratore iota

iota e un identificatore speciale di Go usato all’interno dei blocchi const per generare una sequenza di valori incrementali. Parte da 0 e si incrementa di 1 per ogni riga nel blocco:

package main

import "fmt"

const (
    Lunedi    = iota // 0
    Martedi          // 1
    Mercoledi        // 2
    Giovedi          // 3
    Venerdi          // 4
    Sabato           // 5
    Domenica         // 6
)

func main() {
    fmt.Println("Lunedi:", Lunedi)     // 0
    fmt.Println("Venerdi:", Venerdi)   // 4
    fmt.Println("Domenica:", Domenica) // 6
}

iota con espressioni

Puoi combinare iota con espressioni per creare sequenze personalizzate:

const (
    _  = iota             // ignora il primo valore (0)
    KB = 1 << (10 * iota) // 1 << 10 = 1024
    MB                    // 1 << 20 = 1048576
    GB                    // 1 << 30 = 1073741824
    TB                    // 1 << 40
)

iota per bitmask

iota e molto utile per creare bitmask (maschere di bit):

package main

import "fmt"

const (
    Lettura    = 1 << iota // 1 (001)
    Scrittura              // 2 (010)
    Esecuzione             // 4 (100)
)

func main() {
    // Combina i permessi con OR bitwise
    permessi := Lettura | Scrittura
    fmt.Printf("Permessi: %03b\n", permessi) // 011

    // Verifica un permesso con AND bitwise
    puoLeggere := permessi&Lettura != 0
    puoEseguire := permessi&Esecuzione != 0
    fmt.Println("Puo leggere:", puoLeggere)   // true
    fmt.Println("Puo eseguire:", puoEseguire) // false
}

iota si resetta in ogni blocco const

Ogni nuovo blocco const resetta iota a 0:

const (
    A = iota // 0
    B        // 1
)

const (
    C = iota // 0 (resettato)
    D        // 1
)

Espressioni costanti

Le costanti in Go supportano espressioni che vengono valutate a tempo di compilazione:

package main

import "fmt"

const (
    base    = 10
    doppio  = base * 2
    triplo  = base * 3
    quadro  = base * base
)

const messaggio = "Go e " + "fantastico!"

func main() {
    fmt.Println(doppio)     // 20
    fmt.Println(triplo)     // 30
    fmt.Println(quadro)     // 100
    fmt.Println(messaggio)  // Go e fantastico!
}

Le espressioni costanti possono utilizzare operatori aritmetici, di confronto, logici e la concatenazione di stringhe, ma non possono chiamare funzioni (tranne le funzioni built-in len, cap, real, imag e complex su argomenti costanti).

const lunghezza = len("ciao") // OK: len su una costante stringa

// const risultato = math.Sqrt(4) // ERRORE: non e un'espressione costante

Conclusione

Le costanti in Go garantiscono immutabilita e sicurezza nel codice. La distinzione tra costanti tipizzate e non tipizzate offre flessibilita, mentre iota fornisce un meccanismo elegante per creare enumerazioni e sequenze di valori. Le espressioni costanti, valutate a tempo di compilazione, permettono di definire valori derivati senza alcun costo a runtime.