Введение
В предыдущем разделе мы обсудили часто используемые числовые типы. В этом разделе мы узнаем о символьных типах в Go.
Основные понятия:
- ASCII-кодировка
- UTF-8 кодировка
- Юникод (Unicode)
byte
rune
💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал
В предыдущем разделе мы обсудили часто используемые числовые типы. В этом разделе мы узнаем о символьных типах в Go.
Основные понятия:
byte
rune
В первые дни развития компьютеров использовался формат кодировки ASCII (American Standard Code for Information Interchange). Он представлял символы с использованием 7 бит и мог представить 128 (2^7) символов. Символы с бита 0 по 31 и бит 127 представляли непечатаемые управляющие символы, в то время как символы с бита 32 по 126 представляли обычные заглавные и строчные буквы, цифры и знаки препинания. Подробности см. в таблице.
По мере развития компьютеров возникла необходимость поддержки разных языков. ASCII-кодировка для этого была недостаточной. В результате разные языки разработали свои собственные форматы кодировки, например, GB2312 для упрощенного китайского, EUC - KR для корейского и KOI8 - R для русского.
Однако, учитывая множество языковых семейств в мире, стало необходимо иметь единый формат кодировки, который мог бы объединить все языки. Для этого была создана система Юникод (Unicode).
В 1991 году Консорциум Юникода (Unicode Consortium) выпустил первую версию набора символов Юникод. Его цель заключалась в объединении всех языков в единый формат кодировки, что позволило бы компьютерам по всему миру более легко отображать и обрабатывать текст, а также избегать проблем совместимости в многоязычных средах.
Однако Юникод был только набором символов; он определял коды символов, но не то, как они должны храниться. Это вызвало трудности с широким распространением в течение длительного времени, пока не пришел расцвет Интернета.
С постоянным развитием Интернета популярностью пользуется UTF-8, кодировка реализации Юникода (Unicode). Это кодировка переменной длины, то есть разные символы могут иметь разную длину в байтах в UTF-8.
Например, английские буквы, которые входят в диапазон ASCII, представляются 1 байтом. Символ 'y' (Юникод-значение 121) занимает 1 байт.
В повседневной жизни большинство китайских символов занимает 3 байта. Например, символ '实' (Юникод-значение 23454) занимает 3 байта.
Однако есть некоторые китайские символы, которые занимают 4 байта. Это связано с тем, что существует более 100 000 китайских символов, но, как показано на диаграмме ниже, 3 байта могут представить только немного более 60 000 символов, поэтому небольшое количество китайских символов требует 4 байт для представления.
Еще одно преимущество UTF-8 кодировки заключается в том, что она обратно совместима с ASCII-кодировкой. Фактически, ASCII является подмножеством UTF-8. Первые 128 символов в UTF-8 соответствуют по одному символу ASCII. Это означает, что программное обеспечение, изначально использующее ASCII, может продолжать использоваться с минимальными или без изменений. Благодаря этим преимуществам UTF-8 постепенно стал предпочтительным форматом кодировки.
Создатели языка программирования Go, Роб Пайк (Rob Pike) и Кен Томпсон (Ken Thompson), также изобрели UTF-8, поэтому Go имеет особую привязанность к UTF-8. Go требует, чтобы файлы исходного кода сохранялись в UTF-8 кодировке. При работе с текстовыми символами UTF-8 кодировка является предпочтительным выбором. Более того, стандартная библиотека предоставляет множество функций, связанных с кодированием и декодированием UTF-8.
byte
является псевдонимом для uint8
и занимает один байт (8 бит). Он может быть использован для представления всех символов из таблицы ASCII. Однако, поскольку byte
может представлять ограниченный диапазон значений (256 или 2^8), при работе с составными символами, такими как китайские символы, нам нужно использовать тип rune
.
Создайте новый файл с именем byte.go
и введите следующий код:
cd ~/project
touch byte.go
package main
import "fmt"
func main() {
var a byte = 76
fmt.Printf("Value of a: %c\n", a)
var b uint8 = 76
fmt.Printf("Value of b: %c\n", b)
var c byte = 'L'
fmt.Printf("Value of c: %c\n", c)
}
После запуска программы будет выведен следующий результат:
go run byte.go
Value of a: L
Value of b: L
Value of c: L
Заглушка %c
используется для вывода символов. Можно видеть, что типы byte
и uint8
дают одинаковый вывод, когда их значения совпадают. Если обратиться к таблице ASCII, то можно увидеть, что ASCII-значение буквы 'A' равно 65. Когда мы используем заглушку для целых чисел %d
для вывода значения, оно также равно 65.
Таким образом, очевидно, что byte
в Go эквивалентен uint8
среди целочисленных типов. То же самое относится к rune
, но он представляет другой диапазон целочисленных значений.
rune
является псевдонимом для int32
и занимает четыре байта (32 бита). Он используется для представления составных символов, таких как эмодзи.
Обновите файл byte.go
следующим кодом:
package main
import "fmt"
func main() {
var a rune = '😊' // Smile emoji
fmt.Printf("Value of a: %c\n", a)
var b int32 = 9829 // Decimal representation of a Unicode character (Heart symbol)
fmt.Printf("Value of b: %c\n", b)
var c rune = 0x1F496 // Hexadecimal representation of a Unicode character (Sparkling heart emoji)
fmt.Printf("Value of c: %c\n", c)
var d rune = '\u0041' // Unicode character represented by its code point (Capital letter 'A')
fmt.Printf("Value of d: %c\n", d)
var e rune = '\U0001F609' // Unicode character represented by its code point (Winking face emoji)
fmt.Printf("Value of e: %c\n", e)
}
После запуска программы будет выведено следующее:
go run byte.go
Примечание: Запускайте программу в терминале на рабочем столе или в WebIDE, но не в терминале, расположенном в верхней части виртуальной машины LabEx.
Value of a: 😊
Value of b: ♥
Value of c: 💖
Value of d: A
Value of e: 😉
Примечание: В Go одинарные и двойные кавычки не эквивалентны. Одинарные кавычки используются для представления символов, в то время как двойные кавычки используются для объявления строк. Поэтому при объявлении типов byte
и rune
следует использовать одинарные кавычки, иначе возникнет ошибка.
Теперь давайте закрепим то, что мы узнали. Создайте новый файл с именем rune.go
и введите следующий код. Завершите код так, чтобы шестнадцатеричное число 0x1F648
было присвоено переменной a
, и программа корректно вывела его значение.
rune.go
должен быть расположен в директории ~/project
.package main
import "fmt"
func main() {
var a rune = 0x1F648
fmt.Printf("The value of a is: %c\n", a)
}
Давайте повторим то, что мы узнали в этом разделе:
В этом разделе мы сначала объяснили, что такое ASCII, UTF-8 и Юникод. Затем мы рассмотрели взаимосвязь между символьными типами данных byte и rune и целочисленными типами данных.