Das hängt davon ab, ob Sie über Code-Einheiten oder Codepunkte iterieren möchten. Die Sprache selbst iteriert über Arrays von Array-Elementen und Strings sind Anordnungen von Codeeinheiten, wenn Sie also einfach foreach
mit Typinferenz verwenden, dann mit
foreach(c; "La Verité")
writeln(c);
den letzten beiden Zeichen Kauderwelsch wäre gedruckt, weil é
a Codepunkt, der aus zwei UTF-8-Code-Einheiten besteht, und Sie drucken einzelne Code-Einheiten aus (da char
eine UTF-8-Code-Einheit ist). Während, wenn Sie das tun
foreach(dchar c; "La Verité")
writeln(c);
dann der Laufzeit wird die Codeeinheiten zu Codepunkten dekodieren und é
wird als letztes Zeichen gedruckt werden. Aber nichts davon funktioniert wirklich auf Strings als Bereiche. foreach
arbeitet nativ mit Arrays, ohne die Eingabebereichs-API zu verwenden. Doch für alle String-Typen, sieht der Bereich API wie
@property bool empty();
@property dchar front();
void popFront();
Es auf Strings als Bereiche dchar
arbeitet - nicht ihren Code Einheitentyp. Dies vermeidet Probleme mit Funktionen wie std.algorithm.filter
, die auf einzelnen Code-Einheiten arbeiten, da dies keinen Sinn ergeben würde. Der Umgang mit Codepunkten ist auch nicht 100% richtig, da Unicode sehr kompliziert wird in Bezug auf die Kombination von Codepunkten und Graphemen und so weiter, aber die Arbeit mit Codepunkten ist viel näher an der Korrektheit (und ich glaube, es wird an der Erweiterung gearbeitet) Unterstützung von Graphemen in der Standardbibliothek für die Fälle, in denen Sie dies benötigen und bereit sind, den Leistungshit zu zahlen). Also, API, um den Bereich mit für Saiten auf sie als Bereiche von dchar
arbeiten weit mehr richtig, und wenn man etwas tut, wie
foreach(c; filter!"true"("La Verité"))
writeln(c);
würden Sie Iterieren vorbei sein dchar
und é
würde richtig gedruckt.Der Nachteil all dessen ist natürlich die Tatsache, dass foreach
on Strings standardmäßig auf der Ebene der Code-Einheit arbeitet, während die Range-API für Strings als Codepunkte auf ihnen arbeitet, so dass Sie beim Mischen von Array-Operationen und range-based vorsichtig sein müssen Operationen auf Strings. Deshalb werden string
und wstring
nicht als Random-Access-Bereiche betrachtet - nur bidirektionale Bereiche. Sie können in O (1) keinen wahlfreien Zugriff auf Codepunkte ausführen, wenn sie aus einer unterschiedlichen Anzahl von Codeeinheiten bestehen (wobei dstring
ein Random-Access-Bereich ist, da bei UTF-32 jede Codeeinheit ein Codepunkt).
http://ddili.org/ders/d.en/ranges.html – sigod
@sigod, ja, sollte Alis Buch überprüft haben! Es ist definitiv die Ressource für das Lesen von D-Sachen im Moment. –