2012-09-05 93 views
7

我嘗試編譯下面的代碼:std.algorithm.joiner(string [],string) - 爲什麼result元素是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 zdchar z做修復該錯誤消息,但我想知道爲什麼它會出現在第一名。

爲什麼joiner(string[],string).front()的結果是dchar而不是char?

(沒有什麼關於這方面的文件http://dlang.org/phobos/std_algorithm.html#joiner

回答

11

所有字符串被視爲的dchar範圍。這是因爲一個dchar保證是單個代碼點,因爲在UTF-32中,每個代碼單元是一個代碼點,而在UTF-8(char)和UTF-16(wchar)中,每個代碼的代碼單元數點變化。所以,如果你在個人char s或wchar s上操作,你將會操作一些角色而不是整個角色,這將會非常糟糕。如果你對unicode不太瞭解,建議閱讀Joel Spolsky的this article。它很好地解釋了事情。

在任何情況下,因爲個人char S和wchar經營沒有意義的charwchar字符串被視爲的dchar範圍(ElementType!stringdchar),這意味着儘可能的範圍而言,他們沒有lengthhasLength!stringfalse - 需要walkLength被用來獲取它們的長度),都沒有可切片(hasSlicing!stringfalse),而不是可轉位(isRandomAccess!stringfalse)。這也意味着從任何類型的字符串構建新範圍的任何內容都將導致dchar的範圍。 joiner就是其中之一。有一些函數可以理解unicode和特殊情況下的字符串以提高效率,利用長度,切片和索引來儘可能地利用它們,但除非它們的結果最終是原始的一部分,否則它們返回的任何範圍都將不得不作出的dchar s。

因此,front在任何字符範圍內將始終爲dchar,popFront將始終彈出完整的代碼點。

如果您對範圍瞭解不多,建議您閱讀this。這是關於D的一本書的一章,它是在線的,目前是關於我們的範圍的最佳教程。我們真的應該得到一個關於範圍的適當文章(包括他們如何使用字符串)到dlang.org,但沒有人到處去寫它。無論如何,你至少需要掌握一些基本的範圍,以便能夠使用很多D的標準庫(特別是std.algorithm),因爲它非常重要。

相關問題