如何在D中讀取一行作爲範圍?如何在D中按字符讀取字符串?
我知道D中有範圍,但我只是想知道如何簡單地使用這個概念迭代字符串的每個字符?
爲了顯示我後,在圍棋中類似的代碼是:
for _, someChar := range someString {
// Do something
}
如何在D中讀取一行作爲範圍?如何在D中按字符讀取字符串?
我知道D中有範圍,但我只是想知道如何簡單地使用這個概念迭代字符串的每個字符?
爲了顯示我後,在圍棋中類似的代碼是:
for _, someChar := range someString {
// Do something
}
這取決於您是否要遍歷代碼單元或代碼點。語言本身遍歷由陣列元件陣列和字符串的代碼單元陣列,因此,如果簡單地使用foreach
與類型推斷,然後用
foreach(c; "La Verité")
writeln(c);
印刷將是無意義的最後兩個字符,因爲é
是一個代碼點由兩個UTF-8代碼單元組成,並且您正在打印單個代碼單元(因爲char
是UTF-8代碼單元)。然而,如果你做
foreach(dchar c; "La Verité")
writeln(c);
則運行時將代碼單元進行解碼,以代碼點和é
將印作爲最後一個字符。但是,這些都不是真正以字符串爲範圍進行操作的。 foreach
本地操作數組而不必使用輸入範圍API。然而,對於所有字符串類型,範圍API看起來像
@property bool empty();
@property dchar front();
void popFront();
它運行在字符串作爲dchar
範圍 - 不他們的代碼的單位類型。這避免了像std.algorithm.filter
這樣的函數在單個代碼單元上運行的問題,因爲這樣做沒有意義。在代碼點上進行操作也不是100%正確的,因爲Unicode在代碼點和字形等方面非常複雜,但是在代碼點上操作更接近正確(我相信在添加範圍方面正在做的工作在需要的情況下支持將字形支持到標準庫中,並願意支付性能上的支出)。因此,具有範圍API的字符串操作它們作爲dchar
範圍是更正確的,如果你不喜歡的東西
foreach(c; filter!"true"("La Verité"))
writeln(c);
你會循環訪問dchar
,並é
會正確打印。所有這一切的缺點是,字符串上的foreach
默認在代碼單元級別上運行,而字符串的範圍API在代碼點上對它們進行操作,因此在混合數組操作和基於範圍的操作時必須小心字符串操作。這也是爲什麼string
和wstring
不被視爲隨機存取範圍 - 只是雙向範圍。當它們由不同數量的代碼單元組成時,您不能在代碼點上進行O(1)中的隨機訪問(而dstring
是是隨機訪問範圍,因爲對於UTF-32,每個代碼單元都是代碼點)。
foreach(ch; str)
do_something(ch);
字符串是一個InputRange
。一個InputRange
實現了三件事:
foreach「理解」如何使用範圍,所以它「只是工作」。
但我不會說Go,所以我不完全確定我們說的是同一種語言。
是的,當然,呃,不知道我怎麼會忘記這個,已經用過幾次了,所以我應該知道它......昨天晚上得怪怪睡眠不足:) –
我聽到你,此刻我並不完全清醒。 – 0b1100110
雖然這裏注意類型推斷。該代碼正在遍歷代碼單元,而不是代碼點,所以它不太可能正確操作Unicode。 –
http://ddili.org/ders/d.en/ranges.html – sigod
@sigod,yea,應該檢查阿里的書!這絕對是現在閱讀D資源的資源。 –