我尝试编译以下代码:
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
}
Run Code Online (Sandbox Code Playgroud)
dmd
带有错误的结尾编译:
test.d(8): Error: cannot implicitly convert expression (joiner(x,space).front()) of type dchar to char
Run Code Online (Sandbox Code Playgroud)
更改char z
为dchar z
确定错误消息,但我很感兴趣,为什么它出现在第一位.
为什么结果joiner(string[],string).front()
是dchar而不是char?
(文档http://dlang.org/phobos/std_algorithm.html#joiner中没有任何内容)
Jon*_*vis 11
所有字符串都被视为范围dchar
.这是因为a dchar
保证是单个代码点,因为在UTF-32中,每个代码单元都是代码点,而在UTF-8(char
)和UTF-16(wchar
)中,每个代码点的代码单元数量不同.所以,如果你是在个人char
或者wchar
s上操作,那么你将使用角色而不是整个角色进行操作,这将是非常糟糕的.如果你对unicode了解不多,我建议你阅读Joel Spolsky 撰写的这篇文章.它解释得很好.
在任何情况下,由于个人操作char
S和wchar
s没有意义的字符串char
和wchar
被视为范围dchar
(ElementType!string
是dchar
),这意味着尽可能的范围而言,他们没有length
(hasLength!string
是false
- walkLength
需要使用得到它们的长度),不可切片(hasSlicing!string
是false
),并且不可索引(isRandomAccess!string
是false
).这也意味着从任何类型的字符串构建新范围的任何东西都将产生一系列dchar
.joiner
就是其中之一.有一些函数可以理解unicode和特殊情况字符串的效率,利用长度,切片和索引尽可能,但除非它们的结果最终是原始的一部分,否则它们返回的任何范围都必须被制作的dchar
秒.
因此,front
在任何范围的字符将永远是dchar
,popFront
并将始终弹出一个完整的代码点.
如果您对范围知之甚少,我建议您阅读本文.这是关于D的书中的一章,它是在线的,目前是关于范围的最佳教程.我们真的应该在dlang.org上找到关于范围的适当文章(包括它们如何使用字符串),但是还没有人编写它.无论如何,你至少需要掌握范围的基本知识才能使用很多D的标准库(特别是std.algorithm),因为它非常使用它们.