รˆ uscito il Corso Java Completo โ€” usa il coupon JAVA2026 (fino al 30 giugno)

Rune in Go

In Go, una rune rappresenta un singolo punto di codice Unicode. Il tipo rune รจ un alias per int32, capace di rappresentare qualsiasi carattere Unicode.

Stringhe e Byte vs Rune

In Go, una stringa รจ una sequenza di byte, non di caratteri. Questo รจ importante perchรฉ i caratteri Unicode possono occupare piรน di un byte:

s := "Ciao ๐ŸŒ"
fmt.Println(len(s))          // 10 (byte)
fmt.Println(utf8.RuneCountInString(s)) // 6 (caratteri)

Il carattere โ€œ๐ŸŒโ€ occupa 4 byte in UTF-8, ma รจ una singola rune.

Dichiarare una Rune

var lettera rune = 'A'       // 65
var emoji rune = '๐Ÿš€'         // 128640
var unicode rune = '\u0041'   // 'A' con notazione Unicode
var hex rune = '\x41'         // 'A' con notazione esadecimale

fmt.Printf("%c %d\n", lettera, lettera) // A 65
fmt.Printf("%c %U\n", emoji, emoji)     // ๐Ÿš€ U+1F680

Iterare su una Stringa per Rune

Il ciclo for range su una stringa itera automaticamente per rune:

for i, r := range "Cafรฉ ๐Ÿ‡ฎ๐Ÿ‡น" {
    fmt.Printf("Byte %d: %c (U+%04X)\n", i, r, r)
}

Senza range, si iterano i singoli byte:

s := "Ciao"
for i := 0; i < len(s); i++ {
    fmt.Printf("%c ", s[i]) // Itera byte per byte
}

Conversione tra String, []rune e []byte

s := "Ciao ๐ŸŒ"

// String โ†’ []rune (per manipolare i caratteri)
rune_slice := []rune(s)
fmt.Println(len(rune_slice)) // 6
rune_slice[5] = '๐Ÿš€'
fmt.Println(string(rune_slice)) // "Ciao ๐Ÿš€"

// String โ†’ []byte (per manipolare i byte)
byte_slice := []byte(s)
fmt.Println(len(byte_slice)) // 10

// Rune singola โ†’ String
fmt.Println(string('A'))     // "A"
fmt.Println(string(128640))  // "๐Ÿš€"

Pacchetto unicode

Il pacchetto unicode fornisce funzioni per classificare le rune:

import "unicode"

fmt.Println(unicode.IsLetter('A'))  // true
fmt.Println(unicode.IsDigit('5'))   // true
fmt.Println(unicode.IsSpace(' '))   // true
fmt.Println(unicode.IsUpper('A'))   // true
fmt.Println(unicode.IsLower('a'))   // true
fmt.Println(unicode.ToUpper('a'))   // 'A'
fmt.Println(unicode.ToLower('Z'))   // 'z'

Pacchetto unicode/utf8

import "unicode/utf8"

s := "Ciao ๐ŸŒ"

// Contare i caratteri reali
fmt.Println(utf8.RuneCountInString(s)) // 6

// Decodificare la prima rune
r, size := utf8.DecodeRuneInString(s)
fmt.Printf("%c occupa %d byte\n", r, size) // C occupa 1 byte

// Verificare se una sequenza รจ UTF-8 valida
fmt.Println(utf8.ValidString(s)) // true

Quando Usare []rune

Converti a []rune quando devi:

  • Accedere a un carattere per indice
  • Invertire una stringa
  • Contare o manipolare singoli caratteri
func invertiStringa(s string) string {
    rune_s := []rune(s)
    for i, j := 0, len(rune_s)-1; i < j; i, j = i+1, j-1 {
        rune_s[i], rune_s[j] = rune_s[j], rune_s[i]
    }
    return string(rune_s)
}

fmt.Println(invertiStringa("Ciao ๐ŸŒ")) // "๐ŸŒ oaiC"

Conclusione

Le rune sono essenziali per gestire correttamente il testo Unicode in Go. Ricorda: len() conta i byte, non i caratteri; usa utf8.RuneCountInString() per il conteggio reale. Quando devi manipolare singoli caratteri, converti la stringa in []rune.