Direct naar de hoofdinhoud
Module 4 · Les 4 van 519/50 in de cursus~12 min
Modulelessen (4/5)

Tekenreeksen, bytes en runen

In Go is een string een onveranderlijke reeks bytes. Letterlijke tekenreeks zijn gecodeerd in UTF-8. Een rune is een alias voor int32 en vertegenwoordigt een enkel Unicode codepunt.

Het is essentieel om het verschil tussen bytes en runen te begrijpen vermijd bugs wanneer een string accenten, emoji's, ideogrammen of wat dan ook bevat niet-ASCII-teken.

string = bytes, geen tekens

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) retourneert het aantal bytes, niet zichtbare tekens. Het indexeren van s[i] retourneert de i-de byte (uint8), niet het teken.

for range herhaalt runen

for i, r := range s decodeert UTF-8 on-the-fly: i is de byte-offset van het begin van de rune, is r de rune (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): indexering per teken

Expliciete conversie: wijst een nieuw stuk runen toe. Kostbaar maar soms nodig:

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

string(runes) is de omgekeerde conversie: neemt een []rune en levert een UTF-8-reeks.

Snaren zijn onveranderlijk

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

Om te muteren, converteren naar []byte of []rune, bedienen, terug converteren:

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

Aaneenschakeling

De operator + werkt, maar wordt voor veel aaneenschakelingen in een lus gebruikt strings.Builder (efficiënter, vermijdt tussentijdse toewijzingen):

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

Handige pakketten

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

Probeer het

Oefening#go.m4.l4.e1
Pogingen: 0Laden…

Herhaal de string s met bereik en print index en rune met %d %c.

Editor laden…
Toon hint

bereik over een string retourneert byte-offset + rune.

Oplossing beschikbaar na 3 pogingen

Oefening#go.m4.l4.e2
Pogingen: 0Laden…

Converteer s naar []rune en druk de lengte ervan af in tekens.

Editor laden…
Toon hint

Expliciete conversie: `[]rune(s)`.

Oplossing beschikbaar na 3 pogingen

Quiz#go.m4.l4.e3
Klaar

Wat is len("ciaò")?

Go
s := "ciaò"
fmt.Println(len(s))
Antwoordmogelijkheden

Samenvatten

  • string = onveranderlijke reeks bytes, UTF-8 gecodeerd.
  • len(s) = bytes; s[i] = de i-de byte (uint8).
  • for i, r := range s decodeert runen; i is de byte-offset.
  • []rune(s) om te indexeren op teken (duur, toewijzing).
  • Om te muteren: ga door []byte of []rune.
  • Om in een lus samen te voegen: strings.Builder.
  • Sleutelpakketten: strings, strconv, unicode, unicode/utf8.