Модульні уроки (4/5)
Рядки, байти та руни
У Go string — це незмінна послідовність байтів. Рядкові літерали
закодовані в UTF-8. rune є псевдонімом для int32 та
представляє одну кодову точку Unicode.
Важливо розуміти різницю між байтами та рунами уникайте помилок, коли рядок містить наголоси, емодзі, ідеограми тощо не-ASCII символ.
string = байти, а не символи
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) повертає кількість байтів, невидимих символів.
Індексація s[i] повертає i-й байт (uint8), а не символ.
for range повторює руни
for i, r := range s декодує UTF-8 на льоту: i є зміщенням байтів
початку руни, r є руною (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): посимвольне індексування
Явне перетворення: виділяє новий фрагмент рун. Дорого, але іноді необхідно:
runes := []rune("ciaò")
fmt.Println(len(runes)) // 4
fmt.Println(string(runes[3])) // òstring(runes) є зворотним перетворенням: приймає []rune і створює
рядок UTF-8.
Рядки незмінні
s := "ciao"
// s[0] = 'C' // ERROR: cannot assign to s[0]Щоб мутувати, конвертуйте в []byte або []rune, оперуйте, конвертуйте назад:
b := []byte(s)
b[0] = 'C'
s = string(b) // "Ciao"Конкатенація
Оператор + працює, але для багатьох конкатенацій у циклі використовуйте
strings.Builder (більш ефективний, уникає проміжного розподілу):
var sb strings.Builder
for i := 0; i < 5; i++ {
sb.WriteString("ab")
}
fmt.Println(sb.String()) // "ababababab"Корисні пакети
strings:Contains,HasPrefix,Split,Join,ToUpper,Replace...strconv:Atoi,Itoa,ParseFloat,FormatInt...unicode:IsLetter,IsDigit,ToUpper...unicode/utf8:RuneCountInString(альтернативаlen([]rune(s))).
Спробуйте
Ітерація рядка s з діапазоном і друкованим індексом і руною за допомогою %d %c.
Показати підказку
діапазон над рядком повертає байт-зміщення + руну.
Рішення доступне після 3 спроб
Перетворіть s на []руну та виведіть її довжину в символах.
Показати підказку
Явне перетворення: `[]rune(s)`.
Рішення доступне після 3 спроб
Що таке len("ciaò")?
s := "ciaò"
fmt.Println(len(s))Підведення підсумків
string= незмінна послідовність байтів, закодована UTF-8.len(s)= байтів;s[i]= i-й байт (uint8).for i, r := range sрозшифровує руни;i— зміщення байтів.[]rune(s)для індексування за символами (коштовно, розподіляє).- Щоб змінити: пройдіть через
[]byteабо[]rune. - Для об’єднання в цикл:
strings.Builder. - Ключові пакети:
strings,strconv,unicode,unicode/utf8.