Menu

Unicode в D

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 не имеет информации о длине.

Для получения более детальной информации об авто-декодировании и о том, что оно означает в контексте вашей программы, ознакомьтесь с материалами по ссылкам из раздела "В деталях".

Подробнее

rdmd playground.d