Go podle Příkladů: Řetězce a runy

Řetězec je v Go výřez bajtů určený jen pro čtení. Jazyk i standardní knihovna zacházejí s řetězci zvláštním způsobem - jako s kontejnery textu zakódovaného v UTF-8. V jiných jazycích se řetězce skládají ze “znaků”. V Go se koncept znaku nazývá runa (rune) - je to celé číslo, které reprezentuje Unicode kódový bod. Tento blog post o Go je dobrým úvodem do tématu.

package main
import (
    "fmt"
    "unicode/utf8"
)
func main() {

s je string, kterému je přiřazena literálová hodnota reprezentující slovo “ahoj” v thajštině. Řetězcové literály jsou v Go text zakódovaný v UTF-8.

    const s = "สวัสดี"

Protože řetězce jsou ekvivalentní s []byte, toto vrátí délku surových bajtů, které jsou v něm uložené.

    fmt.Println("Délka:", len(s))

Indexování řetězce vrací surové hodnoty bajtů na každém indexu. Tento cyklus vypíše hexa hodnoty všech bajtů, které tvoří kódové body v s.

    for i := 0; i < len(s); i++ {
        fmt.Printf("%x ", s[i])
    }
    fmt.Println()

Pro spočítání, kolik run je v řetězci, můžeme použít balíček utf8. Všimněte si, že doba běhu RuneCountInString závisí na velikosti řetězce, protože musí postupně dekódovat každou UTF-8 runu. Některé thajské znaky jsou reprezentované UTF-8 kódovými body, které mohou zabírat více bajtů, takže výsledek tohoto počítání může být překvapivý.

    fmt.Println("Počet run:", utf8.RuneCountInString(s))

Cyklus range zachází s řetězci zvláštním způsobem a dekóduje každou runu spolu s jejím posunem v řetězci.

    for idx, runeValue := range s {
        fmt.Printf("%#U začíná na %d\n", runeValue, idx)
    }

Stejné iterace můžeme dosáhnout i explicitním použitím funkce utf8.DecodeRuneInString.

    fmt.Println("\nPomocí DecodeRuneInString")
    for i, w := 0, 0; i < len(s); i += w {
        runeValue, width := utf8.DecodeRuneInString(s[i:])
        fmt.Printf("%#U začíná na %d\n", runeValue, i)
        w = width

Tohle ukazuje předání hodnoty rune funkci.

        examineRune(runeValue)
    }
}
func examineRune(r rune) {

Hodnoty uzavřené v jednoduchých uvozovkách jsou runové literály. Hodnotu rune můžeme přímo porovnat s runovým literálem.

    if r == 't' {
        fmt.Println("nalezeno tý")
    } else if r == 'ส' {
        fmt.Println("nalezeno so sua")
    }
}
$ go run strings-and-runes.go
Délka: 18
e0 b8 aa e0 b8 a7 e0 b8 b1 e0 b8 aa e0 b8 94 e0 b8 b5 
Počet run: 6
U+0E2A 'ส' začíná na 0
U+0E27 'ว' začíná na 3
U+0E31 'ั' začíná na 6
U+0E2A 'ส' začíná na 9
U+0E14 'ด' začíná na 12
U+0E35 'ี' začíná na 15
Pomocí DecodeRuneInString
U+0E2A 'ส' začíná na 0
nalezeno so sua
U+0E27 'ว' začíná na 3
U+0E31 'ั' začíná na 6
U+0E2A 'ส' začíná na 9
nalezeno so sua
U+0E14 'ด' začíná na 12
U+0E35 'ี' začíná na 15

Další příklad: Struktury (struct).