首页 > 解决方案 > 为什么使用 D 中的 char[] 数组抛出类型 Result 的 No [] 运算符重载?

问题描述

我正在玩弄std.range并且std.algorithm遇到了以下问题。

int[] arr1 = [-1, 1, 2, 3, 5, 8];
char[] arr2 = ['a', 'b', 'c', 'd', 'e'];

auto res1 = arr.enumerate.find!(t => t[0] == 4);
auto res2 = arr1.enumerate.find!(t => t[0] == 4);

assert(typeof(res1).stringof == typeof(res2).stringof);

现在,我想访问findwhich is a的结果[Tuple!(ulong, "index", int, "value")(4, 5), Tuple!(ulong, "index", int, "value")(5, 8)]

writeln(res1[0][1]); // 5

我正确地得到了5. 现在,如果我这样做res2等于[Tuple!(ulong, "index", dchar, "value")(4, 'e')]

writeln(res2[0][1]); // Error: no [] operator overload for type Result

抛出异常(抓挠我的头)。您能解释一下为什么它适用于int[]数组而不适用于char[]吗?

更新:如果我打电话res2.array[0][1],它可以工作,但我希望错误信息更能说明问题。

标签: d

解决方案


原因是 Phobos 库认为 int[] 是随机访问,但 char[] 只是顺序访问,因此没有运算符。

好的,这是为什么呢?这就是 D 社区所说的“自动解码”。char[] 是一个 UTF-8 字符串。Phobos 试图提供帮助,将这些 UTF-8 序列转换为一系列代表 Unicode 代码点的 dchar。

UTF-8 序列具有可变长度。大多数英文文本都会有一个字节对应于屏幕上的一个字符,但对于其他语言来说通常不是这样。例如,重音标记可以由各种两个或三个字节序列表示。(在某些情况下它变得更加复杂,各种相同的视觉表示具有不同的内部表示 - std.uni.byGrapheme 是 Phobos 库的一部分,旨在帮助解决这个问题)

无论如何,Phobos - 再次尝试提供帮助,即使我们基本上普遍认为这是一个错误的设计,现在回想起来 - 试图在循环时将那些可能的多字节序列一次压缩为一个 dchar。由于如果不扫描整个字符串直到该点,它就无法知道第 N 个 dchar 在哪里(因为每个 dchar 可能具有不同的长度,并且您必须检查它以了解大小),因此它不能廉价地做到这一点。

由于 [] 运算符应该是廉价的 O(1) 常量时间(和常量内存)操作,因此此实现太复杂而无法确认接口,反而会出现错误。

.array函数只是分配一个大缓冲区并预先完成所有解码工作,而不是按需进行,因此允许随机访问......但是如果您只需要,则可能不需要内存和处理时间看一点结果。


推荐阅读