std.algorithm.joiner(string[],string) - почему элементы результата являются dchar, а не char?
Я пытаюсь скомпилировать следующий код:
import std.algorithm;
void main()
{
string[] x = ["ab", "cd", "ef"]; // 'string' is same as 'immutable(char)[]'
string space = " ";
char z = joiner( x, space ).front(); // error
}
Компиляция с dmd
заканчивается ошибкой:
test.d(8): Error: cannot implicitly convert expression (joiner(x,space).front()) of type dchar to char
изменения char z
в dchar z
действительно исправляет сообщение об ошибке, но мне интересно, почему оно появляется в первую очередь.
Почему результат joiner(string[],string).front()
такое dchar, а не char?
(Ничего об этом нет в документации http://dlang.org/phobos/std_algorithm.html)
1 ответ
Все строки рассматриваются как диапазоны dchar
, Это потому что dchar
гарантированно будет одна кодовая точка, так как в UTF-32 каждая единица кода является кодовой точкой, тогда как в UTF-8 (char
) и UTF-16 (wchar
), количество единиц кода на кодовую точку варьируется. Итак, если вы работали на индивидуальном char
с или wchar
s, вы будете работать с кусочками символов, а не с целыми персонажами, что было бы очень плохо. Если вы не знаете много о юникоде, я бы посоветовал прочитать эту статью Джоэла Спольски. Это объясняет вещи довольно хорошо.
В любом случае, потому что работает на человека char
с и wchar
с не имеет смысла, строки char
а также wchar
рассматриваются как диапазоны dchar
(ElementType!string
является dchar
), то есть, что касается диапазонов, они не имеют length
(hasLength!string
является false
- walkLength
необходимо использовать, чтобы получить их длину), не разрезать (hasSlicing!string
является false
) и не индексируются (isRandomAccess!string
является false
). Это также означает, что все, что строит новый диапазон из любого типа строки, приведет к диапазону dchar
, joiner
является одним из тех. Есть некоторые функции, которые понимают Unicode и строки специального случая для эффективности, используя преимущества длины, нарезки и индексации, где они могут, но если их результат в конечном счете не является срезом оригинала, любой диапазон, который они возвращают, должен быть сделан из dchar
s.
Так, front
на любом диапазоне символов всегда будет dchar
, а также popFront
всегда будет показывать полный код.
Если вы не знаете много о диапазонах, я бы посоветовал прочитать это. Это глава в книге о D, которая находится в сети и в настоящее время является лучшим учебником по диапазонам, которые у нас есть. Мы действительно должны получить надлежащую статью о диапазонах (в том числе о том, как они работают со строками) на http://dlang.org/, но пока никто не удосужился написать ее. В любом случае вам понадобится хотя бы базовое представление о диапазонах, чтобы можно было использовать множество стандартных библиотек D (особенно std.algorithm), потому что они очень интенсивно их используют.