Ответ 1
Если вы счастливы игнорировать суррогатные пары (или, что то же самое, возможность вашего приложения, нуждающегося в символах вне базовой многоязычной плоскости), UTF-16 обладает некоторыми хорошими свойствами, в основном из-за того, что всегда требуется два байта на единицу кода и представляет все BMP в одном блоке кода.
Рассмотрим примитивный тип char
. Если мы используем UTF-8 как представление в памяти и хотим справиться со всеми символами Юникода, насколько это должно быть? Это может быть до 4 байтов... что означает, что нам всегда нужно выделять 4 байта. В этот момент мы могли бы также использовать UTF-32!
Конечно, мы могли бы использовать UTF-32 в качестве представления char
, но UTF-8 в представлении string
, преобразовывая, когда мы идем.
Два недостатка UTF-16:
- Количество единиц кода для символа Юникода является переменной, поскольку не все символы находятся в BMP. До тех пор, пока emoji не стал популярным, это не повлияло на многие приложения в повседневном использовании. В наши дни, конечно, для приложений для обмена сообщениями и т.п. Разработчикам, использующим UTF-16, действительно нужно знать о суррогатных парах.
- Для простого ASCII (который много текста, по крайней мере, на западе) он занимает в два раза больше пространства эквивалентного текста в кодировке UTF-8.
(В качестве побочного примечания я полагаю, что Windows использует UTF-16 для данных Unicode, и для .NET имеет смысл следовать примеру аргументов interop. Это просто задает вопрос на одном шаге.)
Учитывая проблемы суррогатных пар, я подозреваю, что язык/платформа разрабатывались с нуля без требований к взаимодействию (но основываясь на обработке текста в Юникоде), UTF-16 не был бы лучшим выбором. Либо UTF-8 (если вы хотите повысить эффективность памяти и не возражаете против сложности обработки с точки зрения получения до n-го символа), либо UTF-32 (наоборот) будет лучшим выбором. (Даже получение n-го символа имеет "проблемы" из-за таких вещей, как разные формы нормализации. Текст жестко...)