std.algorithm.joiner(string [],string) - 为什么结果元素是dchar而不是char?

时间:2012-09-05 19:31:03

标签: 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 implicitly convert expression (joiner(x,space).front()) of type dchar to char

char z更改为dchar z会修复错误消息,但我很感兴趣,为什么它首先出现。

为什么joiner(string[],string).front()的结果是dchar而不是char?

(文档http://dlang.org/phobos/std_algorithm.html#joiner

中没有任何内容

1 个答案:

答案 0 :(得分:11)

所有字符串都被视为dchar的范围。这是因为dchar保证是单个代码点,因为在UTF-32中,每个代码单元都是代码点,而在UTF-8(char)和UTF-16({{ 1}}),每个代码点的代码单元数量不同。因此,如果您在单个wcharchar上运行,则您将使用字符而不是整个字符进行操作,这将非常糟糕。如果您对unicode了解不多,我建议您阅读Joel Spolsky的this article。它解释得很好。

在任何情况下,由于对单个wcharchar进行操作没有意义,因此将wcharchar的字符串视为{{的范围1}}(wchardchar),这意味着就范围而言,它们没有ElementType!stringdcharlength - { {1}}需要用于获取其长度),不可切片(hasLength!stringfalse),且不可转换(walkLengthhasSlicing!string) 。这也意味着从任何类型的字符串构建新范围的任何内容都将产生false的范围。 isRandomAccess!string就是其中之一。有一些函数可以理解unicode和特殊情况字符串的效率,利用长度,切片和索引尽可能,但除非它们的结果最终是原始的一部分,否则它们返回的任何范围都必须被制作false s。

因此,任何字符范围的dchar始终为joinerdchar将始终弹出完整的代码点。

如果您对范围知之甚少,我建议您阅读this。这是关于D的书中的一章,它是在线的,目前是关于范围的最佳教程。我们真的应该在dlang.org上得到一篇关于范围的适当文章(包括它们如何使用字符串),但还没有人编写它。无论如何,你需要至少掌握一系列范围才能使用很多D的标准库(特别是std.algorithm),因为它非常大量地使用它们。