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

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.