Lekcje modułu (4/5)
Ciągi znaków, bajty i runy
W Go string jest niezmienną sekwencją bajtów. Literały łańcuchowe
są zakodowane w UTF-8. rune jest aliasem dla int32 i
reprezentuje pojedynczy punkt kodowy Unicode.
Zrozumienie różnicy pomiędzy bajtami i runami jest niezbędne unikaj błędów, gdy ciąg znaków zawiera akcenty, emoji, ideogramy lub dowolne inne znak inny niż ASCII.
string = bajty, nie znaki
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) zwraca liczbę bajtów, niewidocznych znaków.
Indeksowanie s[i] zwraca i-ty bajt (uint8), a nie znak.
for range iteruje runy
for i, r := range s dekoduje UTF-8 na bieżąco: i to przesunięcie bajtu
początku runy, r jest runą (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) <- starts at byte 3, takes 2 bytes[]rune(s): indeksowanie według znaków
Jawna konwersja: przydziela nowy kawałek run. Kosztowne, ale czasami konieczne:
runes := []rune("ciaò")
fmt.Println(len(runes)) // 4
fmt.Println(string(runes[3])) // òstring(runes) to konwersja odwrotna: pobiera []rune i generuje
ciąg UTF-8.
Ciągi znaków są niezmienne
s := "ciao"
// s[0] = 'C' // ERROR: cannot assign to s[0]Aby mutować, przekonwertuj na []byte lub []rune, wykonaj operację, przekonwertuj z powrotem:
b := []byte(s)
b[0] = 'C'
s = string(b) // "Ciao"Łączenie
Operator + działa, ale w przypadku wielu konkatenacji w pętli należy go używać
strings.Builder (bardziej wydajny, pozwala uniknąć alokacji pośrednich):
var sb strings.Builder
for i := 0; i < 5; i++ {
sb.WriteString("ab")
}
fmt.Println(sb.String()) // "ababababab"Przydatne pakiety
- KOD 0: KOD 1, KOD PH 2, KOD 3, KOD 4, KOD 5, KOD 6...
- KOD 7: KOD 8, KOD 9, KOD 10, KOD 11...
- KODEKF12: KODEF13, KODEF14, KODEF15...
Contains6:Contains7 (alternatywa dlaContains8).
Spróbuj
Wykonaj iterację ciągu s z zakresem i wydrukuj indeks oraz runę, używając %d %c.
Pokaż wskazówkę
zakres ciągu zwraca przesunięcie bajtu + runę.
Rozwiązanie dostępne po 3 próbach
Konwertuj s na []rune i wydrukuj jego długość w znakach.
Pokaż wskazówkę
Jawna konwersja: `[]rune(s)`.
Rozwiązanie dostępne po 3 próbach
Co to jest len("ciaò")?
s := "ciaò"
fmt.Println(len(s))Podsumowanie
string= niezmienna sekwencja bajtów, zakodowana w formacie UTF-8.len(s)= bajty;s[i]= i-ty bajt (uint8).for i, r := range sdekoduje runy;ito przesunięcie bajtu.[]rune(s)do indeksowania według znaku (kosztowne, przydziela).- Aby mutować: przejdź przez
[]bytelub[]rune. - Aby połączyć w pętli:
strings.Builder. - Kluczowe pakiety:
strings,len(s)0,len(s)1,len(s)2.