s := "Привет"
for i := 0; i < len(s); i++ {
fmt.Printf("Byte %d: %v\n", i, s[i])
}
Особенности:
s := "Привет"
for index, runeValue := range s {
fmt.Printf("Rune %d: %#U\n", index, runeValue)
}
Особенности:
index
- позиция первого байта руны в строкеruneValue
- кодовая точка Unicode (int32)s := "Привет"
runes := []rune(s)
for i, r := range runes {
fmt.Printf("Rune %d: %c\n", i, r)
}
Особенности:
s := "é" // 'e' + combining acute accent
for i, r := range s {
fmt.Printf("%d: %#U\n", i, r) // Выведет две отдельные руны
}
Проблема: Визуально один символ, но технически две руны
Решение: Использовать нормализацию Unicode:
import "golang.org/x/text/unicode/norm"
s := norm.NFC.String("é") // Нормализует в одну руну
s := "hello"
for _, r := range s {
r = 'a' // Не изменяет исходную строку!
}
Важно: Строки в Go неизменяемы. Для модификации нужно:
[]rune
s := "😊♂" // Смайлик + гендерный символ
for i, r := range s {
fmt.Printf("%d: %c\n", i, r) // Корректно обработает
}
s := "\x00Привет\n" // С нулевым байтом и переводом строки
for _, r := range s {
if r == 0 {
fmt.Println("Found null byte!")
}
}
range
по строке: оптимально для UTF-8[]rune
: дополнительная аллокация памятиs := "Привет"
count := len(s) // 12 вместо 6!
s := "hello"
for i := range s {
s[i] = 'a' // Ошибка компиляции!
}
s := "Привет"
runes := []rune(s)
pos := runes[3] // Позиция в рунах ≠ позиция в байтах
for range
[]rune
создает копию данных, но удобен для работыs[i]
) работает только с байтамиВыбор метода итерации зависит от задачи:
for range
[]rune