Unicode - общий стандарт кодирования и представления текста в компьютерах. D полностью поддерживает Unicode как на уровне языка, так и на уровне стандартной библиотеки.
Компьютеры, на самом низком уровне, не имеют понятия о том, что такое текст, поскольку работают исключительно с числами. Как следствие, компьютерный код нуждается в способе преобразования полученных текстовых данных в двоичное представление. Метод преобразования называется кодировкой, и Unicode является одним из таких методов.
Чтобы увидеть числовое представление строк в примере, просто запустите код.
Unicode уникален тем, что его дизайн позволяет представить все языки мира, используя одну и ту же кодировку. До появления Unicode, компьютеры, созданные разными компаниями или поставлявшиеся на разные территории, нельзя было свободно использовать для связи, а в некоторых случаях кодировка и вовсе не поддерживалась, что делало просмотр текста на таком компьютере невозможным.
Для более детального описания Unicode и технических тонкостей, ознакомьтесь со статьёй о Unicode в Википедии (ссылка в разделе "В деталях").
Unicode исправил большинство таких проблем и поддерживается любой современной машиной. D учится на ошибках прошлых языков, поэтому все строки в D являются строками в формате Unicode, тогда как строки в таких языках, как C и C++ - это просто массивы байтов.
В D string
, wstring
и dstring
- это строки, кодированные
в UTF-8, UTF-16 и UTF-32 соответственно. Типы символов в них -
char
, wchar
и dchar
.
Согласно спецификации, хранение не-Unicode данных в строковых типах D является ошибкой; ожидайте различных отказов в программе, если ваши строки неверно кодированы.
Для хранения строк в других кодировках, или для достижения поведения,
аналогичного C/C++, используйте ubyte[]
или char*
.
Рекомендуем прочесть [жемчужину об алгоритмах над диапазонами](gems/range-algorithms) перед прочтением данного раздела.
При работе с Unicode в D нужно помнить о некоторых подводных камнях.
Во-первых, для удобства, при итерировании строк с использованием
функций диапазонов, Phobos кодирует элементы string
и wstring
в кодовые позиции UTF-32. Эта практика, известная как
авто-декодирование, означает, что
static assert(is(typeof(utf8.front) == dchar));
Такое поведение влечёт ряд неявных условий, главное из которых,
путающее большинство людей, состоит в том, что
std.traits.hasLength!(string)
возвращает False
.
Почему? Говоря терминологией API диапазонов, причина в том, что метод
length
типа string
возвращает количество элементов в строке,
а не количество элементов в диапазоне, с которым будет работать функция.
На примере явно видно, почему эти две "длины" не всегда равны.
Именно поэтому алгоритмы над диапазонами в Phobos работают так,
будто string
не имеет информации о длине.
Для получения более детальной информации об авто-декодировании и о том, что оно означает в контексте вашей программы, ознакомьтесь с материалами по ссылкам из раздела "В деталях".