【问题标题】:std.algorithm.joiner(string[],string) - why result elements are dchar and not char?std.algorithm.joiner(string[],string) - 为什么结果元素是 dchar 而不是 char?
【发布时间】:2012-09-05 19:31:02
【问题描述】:

我尝试编译以下代码:

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 中没有任何内容)

【问题讨论】:

    标签: d dmd phobos


    【解决方案1】:

    所有字符串都被视为dchar 的范围。这是因为 dchar 保证是单个代码点,因为在 UTF-32 中,每个代码单元都是一个代码点,而在 UTF-8 (char) 和 UTF-16 (wchar) 中,每个代码点的代码单元数各不相同。因此,如果您在单个 chars 或 wchars 上进行操作,您将在部分字符而不是整个字符上进行操作,这将非常糟糕。如果您对 unicode 不太了解,我建议您阅读 Joel Spolsky 的 this article。它很好地解释了事情。

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

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

    如果您不太了解范围,我建议您阅读this。这是一本关于 D 的书中的一章,它是在线的,是目前我们所拥有的关于范围的最佳教程。我们真的应该在dlang.org 上找到一篇关于范围(包括它们如何处理字符串)的适当文章,但还没有人开始写它。无论如何,您至少需要对范围有基本的了解才能使用很多 D 的标准库(尤其是 std.algorithm),因为它大量使用它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-01
      • 2010-10-04
      • 2015-11-10
      • 1970-01-01
      相关资源
      最近更新 更多