Salt la conținutul principal
Modulul 4 · Lecția 4 din 519/50 în curs~12 min
Lecții din modul (4/5)

Șiruri, octeți și rune

În Go, un string este o secvență imuabilă de octeți. Literale șiruri sunt codificate în UTF-8. Un rune este un alias pentru int32 și reprezintă un singur punct de cod Unicode.

Înțelegerea diferenței dintre octeți și rune este esențială pentru evitați erorile atunci când un șir conține accente, emoji, ideograme sau orice altceva caracter non-ASCII.

string = octeți, nu caractere

Go
s := "ciaò"
fmt.Println(len(s))   // 5 — not 4!
fmt.Println(s[0])     // 99 ('c' as a byte)
fmt.Println(s[3])     // 195 (first byte of 'ò' in UTF-8)

len(s) returnează numărul de octeți, caractere care nu sunt vizibile. Indexarea s[i] returnează al-lea octet (uint8), nu caracterul.

for range repetă rune

for i, r := range s decodifică UTF-8 din mers: i este byte-offset de la începutul runei, r este runa (int32):

Go
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)   <- starts at byte 3, takes 2 bytes

[]rune(s): indexare pe caracter

Conversie explicită: alocă o nouă porțiune de rune. Costos dar uneori necesar:

Go
runes := []rune("ciaò")
fmt.Println(len(runes))    // 4
fmt.Println(string(runes[3])) // ò

string(runes) este conversia inversă: ia un []rune și produce un șir UTF-8.

Corzile sunt imuabile

Go
s := "ciao"
// s[0] = 'C'   // ERROR: cannot assign to s[0]

Pentru a muta, convertiți în []byte sau []rune, operați, convertiți înapoi:

Go
b := []byte(s)
b[0] = 'C'
s = string(b)   // "Ciao"

Concatenare

Operatorul + funcționează, dar pentru multe concatenări într-o buclă utilizați strings.Builder (mai eficient, evită alocările intermediare):

Go
var sb strings.Builder
for i := 0; i < 5; i++ {
    sb.WriteString("ab")
}
fmt.Println(sb.String())   // "ababababab"

Pachete utile

  • strings: Contains, HasPrefix, Split, Join, HasPrefix, Split, Join, PROTECTEDINLINE2424__PROTECTED_24__5...
  • strconv: Atoi, Itoa, ParseFloat, FormatInt...
  • unicode: IsLetter, IsDigit, ToUpper...
  • unicode/utf8: RuneCountInString (alternativă la len([]rune(s))).

Încearcă

Exercițiu#go.m4.l4.e1
Încercări: 0Se încarcă…

Repetați șirul s cu interval și imprimați indicele și runa folosind %d %c.

Se încarcă editorul...
Afișează indiciu

interval peste un șir returnează byte-offset + rună.

Soluție disponibilă după 3 încercări

Exercițiu#go.m4.l4.e2
Încercări: 0Se încarcă…

Convertiți s în []rună și imprimați lungimea acestuia în caractere.

Se încarcă editorul...
Afișează indiciu

Conversie explicită: „[]rune(e)”.

Soluție disponibilă după 3 încercări

Quiz#go.m4.l4.e3
Gata

Ce este len ("ciaò")?

Go
s := "ciaò"
fmt.Println(len(s))
Opțiuni de răspuns

Recapitulare

  • string = secvență imuabilă de octeți, codificat UTF-8.
  • len(s) = octeți; s[i] = al i-lea octet (uint8).
  • for i, r := range s decodifică runele; i este decalajul octet.
  • []rune(s) pentru a indexa după caracter (costisitor, alocă).
  • Pentru a muta: treceți prin []byte sau []rune.
  • Pentru a concatena într-o buclă: strings.Builder.
  • Pachete cheie: strings, strconv, unicode, unicode/utf8.