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), потому что они очень интенсивно их используют.

Другие вопросы по тегам