d-std.algorithm.joiner(string[],string)-为什么结果元素是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 z更改为dchar z确实修复了错误消息,但我很感兴趣的是它最初出现的原因。

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

(文档中没有这方面的内容http://dlang.org/phobos/std_algorithm.html#joiner)

所有字符串都被视为dchar的范围。这是因为dchar保证是单个码点,因为在UTF-32中,每个代码单元都是一个码点,而在UTF-8(char)和UTF-16(wchar)中,每个码点的代码单元数量不同。所以,如果你在单个charwchar上操作,你会在多个字符上操作,而不是整个字符,这将是非常糟糕的。如果你对unicode了解不多,我建议你阅读Joel Spolsky的这篇文章。它很好地解释了事情。

在任何情况下,因为对单个chars和wchars进行操作都没有意义,所以charwchar的字符串被视为dchar的范围(ElementType!stringdchar),这意味着就范围而言,它们没有lengthhasLength!stringfalse-需要使用walkLength来获得它们的长度),不可切片(hasSlicing!stringfalse),并且是不可索引的(isRandomAccess!stringfalse)。这也意味着,任何从任何类型的字符串构建新范围的东西都将导致dchar的范围。CCD_ 27就是其中之一。有些函数为了提高效率,可以理解unicode和特殊情况字符串,尽可能利用长度、切片和索引,但除非它们的结果最终是原始字符串的切片,否则它们返回的任何范围都必须由dchar s组成。

因此,任何字符范围上的front都将始终是dchar,而popFront将始终弹出一个完整的代码点。

如果你对音域了解不多,我建议你读这篇文章。这是一本关于D的书中的一章,这本书是在线的,也是目前我们最好的范围教程。我们真的应该在dlang.org上找到一篇关于范围(包括它们如何处理字符串)的合适文章,但还没有人抽出时间来写。无论如何,您至少需要对范围有一个基本的了解,才能使用大量D的标准库(尤其是std.algorithm),因为它使用得非常多。

最新更新