len() возвращает кол-во байтов (не символов) в строке.
s := "hello, world"fmt.Println(len(s)) // 12
Indexing and slicing
Операция индексированияs[i] возвращает i-й байт строки s (где 0 <= i <= len(s)). i-й байт строки не обязательно является i-м символом строки, ибо кодирока UTF-8 (не ASCII) требует 2 или более байтов.
Т.к. строки неизменяемы, изменить данные строки не получится:
s[0] = 'L' // cannot assign to s[0] (neither addressable nor a map index expression)
Другие профиты иммутабельности
Иммутабельность также означает, что две копии строки могут безопасно храниться в одном и том же участке памяти, что делает копирование строки любой длины очень дешевой операцией. Строкаs и ее подстроки (s[7:], например) могут также безопасно разделять одни и те же данные в памяти, поэтому операция получения подстроки тоже очень дешевая.
Raw string literal
Неформатированный строковый литерал (raw string literal) записывается с помощью символов backtick (`).
Внутри управляющие последовательностине обрабатываются (кроме удалении символа возврата каретки (CR или \r)), оставаясь в сыром виде.
Это особенности дают возможность:
записывать RegEx-ы, в которых бывает много символов backslash (\)
шаблоны HTML
литералы JSON
usage messages
const GoUsage = `Go is a tool for working with Go source code.Usage:go command [arguments]....`
UTF-8
Каждому символу Unicode назначен стандартный номер — код символа Unicode (Unicode code point), или, руна (rune) в терминологии Go.
int32 — естественный тип данных для хранения отдельной руны, который и используется в Go с синонимом (alias) типа rune. И, по идее, можно последовательность рун представлять как последовательность значений int32. Это представление называется UTF-32 или UCS-4, где каждый символ имеет одинаковый размер в 32 бита. Но проблема в том, что это кодирование использует сильно больше необходимой памяти, ибо большинство текстов в компьютерах используют только символы ASCII, которой требуется только 8 битов (1 байт) на символ.
Решение — UTF-8, кодировка переменной длины символов Unicode в виде байтов. Создана была двумя из создателей Go, Ken Thompson и Rob Pike, и является на данный момент стандартом Unicode.
Она использует от 1 до 4 байтов для представления каждой руны, но:
только 1 байт для символов ASCII, что делает его идентичным и совместимым с ASCII
2 или 3 байта для болшинства распространенных рун
Unicode control characters
Многие символы Unicode трудно набирать на клавиатуре, поэтому есть управляющие последовательности Unicode, которые позволяют записывать символы Unicode с помощью их числового кода:
\uhhhh для 16-разрядных значений
\Uhhhhhhhh для 36-разрядных (где каждое h — шестнадцатеричная цифра)
Необходимость в этой разновидности управляющей последовательности Unicode возникает очень редко.
Ниже преведены строковые литералы, представляющие одну и ту же 6-байтовую строку:
Корректность литералов рун, значение которых больше 256
Руна, значение которой меньше 256, может быть записана с помощью одной шестнадцатеричной управляющей последовательности, типа '\x41' для 'A', но для более высоких значений нужно использовать \u или \U.
То есть, \xe4xb8\x96не является корректным литералом руны, хоть и эти три байта являются корректной кодировкой UTF-8 одного символа Unicode.
UTF-8 encoding and decoding
Operations without decoding
Многие строковые операции не требуют декодирования. Например, можно проверить, не является ли одна строка префиксом другого:
func Contains(s, substr string) bool { for i := range len(s) { if HasPrefix(s[i:], substr) { return true } } return false}
используя для закодированного с помощью UTF-8 текста ту же логику, что и для обычной последовательности байтов (для других кодировок это было бы неверным решением). (Приведенные функции выше взяты из пакета strings, хотя Contains там использует хэширование для более эффективного поиска.)
Operations with decoding
Но работать с отдельными символами Unicode нужно по-другому. Ниже приведен пример представления в памяти двух иероглифов, где строка содержит 13 байт, но UTF-8 интерпретация показывает только 9 закодированных кодов Unicode (рун).