std.algorithm.joiner(string[],string)-为什么结果元素是dchar而不是char?
我尝试编译以下代码:std.algorithm.joiner(string[],string)-为什么结果元素是dchar而不是char?,d,dmd,phobos,D,Dmd,Phobos,我尝试编译以下代码: 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 implic
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 z
更改为dchar z
确实修复了错误消息,但我感兴趣的是它为什么会首先出现
为什么joiner(string[],string).front()的结果是dchar而不是char
(文档中没有相关内容)所有字符串都被视为dchar的范围。这是因为dchar
保证是单个代码点,因为在UTF-32中,每个代码单元都是一个代码点,而在UTF-8(char
)和UTF-16(wchar
)中,每个代码点的代码单元数量不同。因此,如果您对单个char
s或wchar
s进行操作,那么您将对单个字符而不是整个字符进行操作,这将非常糟糕。如果您对unicode了解不多,我建议您阅读Joel Spolsky的著作。它很好地解释了事情
在任何情况下,由于对单个char
s和wchar
s进行操作都没有意义,char
和wchar
的字符串被视为dchar
的范围(ElementType!string
是dchar
),这意味着就范围而言,它们没有长度
(hasliging!string
为false
-walkLength
需要用于获取其长度),不可切片(hasliging!string
为false
),也不可索引(israndomacess!string
为false
)。这也意味着,任何从任何类型的字符串构建新范围的函数都将导致dchar
joiner
的范围。有些函数理解unicode和特例字符串以提高效率,尽可能利用长度、切片和索引,但除非它们的结果它最终是原始数据的一部分,它们返回的任何范围都必须由dchar
s组成
因此,任何字符范围上的front
将始终是dchar
,而popFront
将始终弹出完整的代码点
如果你对范围知之甚少,我建议你阅读。这是一本关于d的书中的一章,这本书是在线的,是目前关于范围的最好教程。我们真的应该得到一篇关于范围的适当文章(包括关于它们如何处理字符串的文章)尽管如此,你至少需要对范围有一个基本的掌握,才能使用大量的D标准库(特别是std.algorithm),因为它使用了大量的范围