为什么在 D 中没有使用 char[] 数组抛出 Result 类型的 [] 运算符重载?
Why No [] operator overload for type Result is thrown with char[] array in D?
我在玩 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);
现在,我想访问 find
的结果,它是 [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]
,它可以工作,但我希望错误消息更能说明问题。
原因是 Phobos 库认为 int[] 是随机访问,而 char[] 只是顺序访问,因此没有运算符。
好的,这是为什么呢?这就是D界所说的"autodecoding"。 char[] 是一个 UTF-8 字符串。 Phobos 试图提供帮助,将这些 UTF-8 序列转换为一系列代表 Unicode 代码点的 dchars。
UTF-8 序列长度可变。大多数英文文本将有一个字节对应屏幕上的一个字符,但对于其他语言通常情况并非如此。例如,重音标记可以由各种两字节或三字节序列表示。 (在某些情况下它变得更加复杂,各种相同的视觉表示具有不同的内部表示 - std.uni.byGrapheme 是 Phobos 库的一部分,旨在帮助解决这个问题)
无论如何,Phobos - 再次试图提供帮助,即使我们现在回想起来基本上普遍认为这是一个错误的设计 - 试图在循环时一次将那些可能的多字节序列压缩到一个 dchar。因为它无法知道第 N 个 dchar 在哪里而不扫描整个字符串直到那个点(因为每个 dchar 可能具有不同的长度并且您必须检查它才能知道大小),它不能便宜地做到这一点。
由于 [] 运算符应该是廉价的,O(1) 常数时间(和常数内存)操作,此实现太复杂而无法向接口确认,您反而得到了错误。
.array
函数只分配一个大缓冲区并预先完成所有解码工作,而不是按需进行,因此允许随机访问...但以内存和处理时间为代价如果您只需要查看一点结果,则可能没有必要。
我在玩 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);
现在,我想访问 find
的结果,它是 [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]
,它可以工作,但我希望错误消息更能说明问题。
原因是 Phobos 库认为 int[] 是随机访问,而 char[] 只是顺序访问,因此没有运算符。
好的,这是为什么呢?这就是D界所说的"autodecoding"。 char[] 是一个 UTF-8 字符串。 Phobos 试图提供帮助,将这些 UTF-8 序列转换为一系列代表 Unicode 代码点的 dchars。
UTF-8 序列长度可变。大多数英文文本将有一个字节对应屏幕上的一个字符,但对于其他语言通常情况并非如此。例如,重音标记可以由各种两字节或三字节序列表示。 (在某些情况下它变得更加复杂,各种相同的视觉表示具有不同的内部表示 - std.uni.byGrapheme 是 Phobos 库的一部分,旨在帮助解决这个问题)
无论如何,Phobos - 再次试图提供帮助,即使我们现在回想起来基本上普遍认为这是一个错误的设计 - 试图在循环时一次将那些可能的多字节序列压缩到一个 dchar。因为它无法知道第 N 个 dchar 在哪里而不扫描整个字符串直到那个点(因为每个 dchar 可能具有不同的长度并且您必须检查它才能知道大小),它不能便宜地做到这一点。
由于 [] 运算符应该是廉价的,O(1) 常数时间(和常数内存)操作,此实现太复杂而无法向接口确认,您反而得到了错误。
.array
函数只分配一个大缓冲区并预先完成所有解码工作,而不是按需进行,因此允许随机访问...但以内存和处理时间为代价如果您只需要查看一点结果,则可能没有必要。