Lezioni del modulo (4/5)
Stringhe, byte e rune
In Go una string è una sequenza immutabile di byte. Le stringhe
letterali sono codificate in UTF-8. Una rune è un alias per int32
e rappresenta un singolo code point Unicode.
Capire la differenza tra byte e rune è essenziale per non incappare in bug quando la stringa contiene accenti, emoji, ideogrammi o qualsiasi carattere non-ASCII.
string = byte, non caratteri
s := "ciaò"
fmt.Println(len(s)) // 5 — non 4!
fmt.Println(s[0]) // 99 ('c' come byte)
fmt.Println(s[3]) // 195 (primo byte di 'ò' in UTF-8)len(s) ritorna il numero di byte, non di caratteri visibili.
L'indicizzazione s[i] ritorna il byte i-esimo (uint8), non il
carattere.
for range itera rune
for i, r := range s decodifica UTF-8 al volo: i è il byte-offset
dell'inizio del rune, r è il rune (int32):
s := "ciaò"
for i, r := range s {
fmt.Printf("%d %c (U+%04X)\n", i, r, r)
}
// 0 c (U+0063)
// 1 i (U+0069)
// 2 a (U+0061)
// 3 ò (U+00F2) <- inizia al byte 3, occupa 2 byte[]rune(s): indicizzazione per carattere
Conversione esplicita: aloca un nuovo slice di rune. Costoso ma a volte necessario:
runes := []rune("ciaò")
fmt.Println(len(runes)) // 4
fmt.Println(string(runes[3])) // òstring(runes) è la conversione inversa: prende uno []rune e produce
una stringa UTF-8.
Stringhe sono immutabili
s := "ciao"
// s[0] = 'C' // ERRORE: cannot assign to s[0]Per modificare, converti in []byte o []rune, opera, riconverti:
b := []byte(s)
b[0] = 'C'
s = string(b) // "Ciao"Concatenazione
L'operatore + funziona, ma per molte concatenazioni in loop usa
strings.Builder (più efficiente, evita allocazioni intermedie):
var sb strings.Builder
for i := 0; i < 5; i++ {
sb.WriteString("ab")
}
fmt.Println(sb.String()) // "ababababab"Pacchetti utili
strings:Contains,HasPrefix,Split,Join,ToUpper,Replace...strconv:Atoi,Itoa,ParseFloat,FormatInt...unicode:IsLetter,IsDigit,ToUpper...unicode/utf8:RuneCountInString(alternativa alen([]rune(s))).
Prova tu
Itera la stringa s con range e stampa indice e rune con %d %c.
Mostra suggerimento
range su string ritorna byte-offset + rune.
Soluzione disponibile dopo 3 tentativi
Converti s in []rune e stampa la sua lunghezza in caratteri.
Mostra suggerimento
Conversione esplicita: `[]rune(s)`.
Soluzione disponibile dopo 3 tentativi
Quanto vale len("ciaò")?
s := "ciaò"
fmt.Println(len(s))Recap
string= sequenza immutabile di byte, codificata UTF-8.len(s)= byte;s[i]= byte i-esimo (uint8).for i, r := range sdecodifica rune;iè il byte-offset.[]rune(s)per indicizzare per carattere (costoso, alloca).- Per modificare: passa via
[]byteo[]rune. - Per concatenare in loop:
strings.Builder. - Pacchetti chiave:
strings,strconv,unicode,unicode/utf8.