Функция utf8.DecodeRune
Функция utf8.DecodeRune декодирует первый символ Unicode
(руну) из байтового среза. Она возвращает два значения:
декодированную руну и количество байт, которые она заняла.
В качестве единственного параметра функция принимает байтовый
срез []byte. Если срез начинается с некорректной
UTF-8 последовательности, функция возвращает специальную руну
utf8.RuneError (которая равна U+FFFD) и
значение 1 (один байт считает некорректным).
Синтаксис
runeValue, size := utf8.DecodeRune(p)
Где p — байтовый срез []byte, с которого
начинается декодирование.
Пример
Давайте декодируем первую руну из байтового среза, содержащего строку "Hello":
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
data := []byte("Hello")
r, size := utf8.DecodeRune(data)
fmt.Printf("Руна: %q, Размер: %d\n", r, size)
}
Результат выполнения кода:
"Руна: 'H', Размер: 1"
Мы видим, что латинская буква 'H' занимает 1 байт в UTF-8.
Пример
Теперь давайте декодируем первую руну из байтового среза, содержащего кириллическую строку "Привет":
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
data := []byte("Привет")
r, size := utf8.DecodeRune(data)
fmt.Printf("Руна: %q, Размер: %d\n", r, size)
}
Результат выполнения кода:
"Руна: 'П', Размер: 2"
Буква 'П' в UTF-8 кодируется двумя байтами, что и показывает функция.
Пример
Давайте посмотрим, как функция реагирует на некорректные UTF-8 данные. Предположим, что у нас есть байтовый срез, содержащий неполную последовательность:
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
// Некорректная UTF-8 последовательность (0xC2 - это
// начало двухбайтовой последовательности, но нет продолжения)
data := []byte{0xC2}
r, size := utf8.DecodeRune(data)
fmt.Printf("Руна: %q, Размер: %d\n", r, size)
}
Результат выполнения кода:
"Руна: '�', Размер: 1"
В этом случае функция возвращает специальную руну ошибки
utf8.RuneError (отображается как '�') и размер 1,
указывая на то, что один байт был обработан как некорректный.
Пример
Функция также может быть использована для итерации по всем рунам в байтовом срезе. Давайте пройдемся по строке "Go-язык":
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
data := []byte("Go-язык")
for i := 0; i < len(data); {
r, size := utf8.DecodeRune(data[i:])
fmt.Printf("Руна: %q, позиция: %d\n", r, i)
i += size
}
}
Результат выполнения кода:
"Руна: 'G', позиция: 0"
"Руна: 'o', позиция: 1"
"Руна: '-', позиция: 2"
"Руна: 'я', позиция: 3"
"Руна: 'з', позиция: 5"
"Руна: 'ы', позиция: 7"
"Руна: 'к', позиция: 9"
В этом примере видно, как руны смещаются по позициям: латиница и дефис занимают по 1 байту, а кириллические буквы занимают по 2 байта.
Смотрите также
-
функцию
utf8.DecodeRuneInString,
которая декодирует первую руну из строки -
функцию
utf8.DecodeLastRune,
которая декодирует последнюю руну из байтового среза -
функцию
utf8.RuneCount,
которая подсчитывает количество рун в байтовом срезе -
функцию
utf8.Valid,
которая проверяет, является ли байтовый срез корректным UTF-8