2012-09-05 5 views
7

Ich versuche folgenden Code zu kompilieren:std.algorithm.joiner (string [], string) - warum Ergebniselemente sind dchar und nicht 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 
} 

Compilation mit dmd endet mit Fehler:

test.d(8): Error: cannot implicitly convert expression (joiner(x,space).front()) of type dchar to char 

Ändern char z-dchar z bedeutet die Fehlermeldung beheben, aber ich bin interessiert, warum es in der erscheint erster Platz.

Warum Ergebnis ist dchar und nicht char?

(Es gibt nichts auf dieser in der Dokumentation http://dlang.org/phobos/std_algorithm.html#joiner)

Antwort

11

Alle Strings als Bereiche von dchar behandelt werden. Dies liegt daran, dass dchar garantiert ein einzelner Codepunkt ist, da in UTF-32 jede Codeeinheit ein Codepunkt ist, während in UTF-8 (char) und UTF-16 (wchar) die Anzahl der Codeeinheiten pro Code angegeben ist Punkt variiert. Also, wenn Sie auf einzelnen char s oder wchar s betrieben würden, würden Sie auf Stücken von Zeichen statt ganze Zeichen operieren, was sehr schlecht wäre. Wenn Sie nicht viel über Unicode wissen, würde ich empfehlen, this article von Joel Spolsky zu lesen. Es erklärt die Dinge ziemlich gut.

Auf jeden Fall, denn auf einzelne char s und wchar s arbeitet sie nicht sinnvoll, Streicher von char und wchar behandelt werden als Bereiche von dchar (ElementType!string ist dchar), was bedeutet, dass bis Bereiche betroffen sind, nicht length haben (hasLength!string ist false-walkLength Bedarf verwendet werden, um ihre Länge zu bekommen), nicht schneidbar (hasSlicing!string ist false) und sind nicht Wende (isRandomAccess!string ist false). Dies bedeutet auch, dass alles, was einen neuen Bereich von jeder Art von String erzeugt, zu einer Reihe von dchar führen wird. joiner ist einer von denen. Es gibt einige Funktionen, die die Effizienz von Unicode- und Sonderfällen verstehen, indem sie die Vorteile von Länge, Slicing und Indizierung nutzen, wo sie können, aber wenn ihr Ergebnis nicht letztlich ein Stück des Originals ist, muss jeder zurückgelegte Bereich gemacht werden von dchar s.

So wird front auf einen Bereich von Zeichen immer dchar sein, und popFront wird immer einen vollständigen Codepunkt abspringen.

Wenn Sie nicht viel über Bereiche wissen, würde ich empfehlen, this zu lesen. Es ist ein Kapitel in einem Buch über D, das online ist und derzeit das beste Tutorial über Bereiche ist, die wir haben. Wir sollten wirklich einen richtigen Artikel über Bereiche (einschließlich, wie sie mit Strings arbeiten) auf dlang.org bekommen, aber niemand ist dazu gekommen, es noch zu schreiben. Unabhängig davon müssen Sie zumindest ein grundlegendes Verständnis der Bereiche haben, um in der Lage zu sein, viele Ds-Standardbibliotheken (insbesondere Std.Algorithmen) zu verwenden, da sie diese sehr stark verwenden.