gpt4 book ai didi

d - 如何逐个字符地读取字符串作为 D 中的范围?

转载 作者:行者123 更新时间:2023-12-04 03:20:14 25 4
gpt4 key购买 nike

如何将一行读取为 D 中的范围?

我知道 D 中有范围,但我只是想知道如何使用这个概念简单地迭代字符串的每个字符?

为了显示我的目标,Go 中的类似代码是:

for _, someChar := range someString {
// Do something
}

最佳答案

这取决于您是要迭代代码单元还是代码点。语言本身通过数组元素迭代数组,而字符串是代码单元的数组,所以如果你简单地使用 foreach使用类型推断,然后使用

foreach(c; "La Verité")
writeln(c);

打印的最后两个字符会是乱码,因为 é是由两个 UTF-8 代码单元组成的代码点,并且您正在打印单个代码单元(因为 char 是一个 UTF-8 代码单元)。然而,如果你这样做
foreach(dchar c; "La Verité")
writeln(c);

然后运行时会将代码单元解码为代码点,并且 é将作为最后一个字符打印。但这些都不是真正将字符串作为范围操作。 foreach native 对数组进行操作,而无需使用输入范围 API。但是,对于所有字符串类型,范围 API 看起来像
@property bool empty();
@property dchar front();
void popFront();

它对字符串进行操作,范围为 dchar - 不是他们的代码单元类型。这避免了像 std.algorithm.filter 这样的函数的问题。对单个代码单元进行操作,因为那毫无意义。对码点的操作也不是 100% 正确,因为 Unicode 在组合码点和字素等方面变得非常复杂,但对码点的操作更接近于正确(我相信在增加范围方面正在做一些工作)在您需要并愿意支付性能损失的情况下,将字素支持到标准库中)。因此,将字符串的范围 API 作为范围对它们进行操作 dchar更正确,如果你做了类似的事情
foreach(c; filter!"true"("La Verité"))
writeln(c);

你会遍历 dchar , 和 é会正确打印。当然,所有这些的缺点是 foreach默认情况下,字符串在代码单元级别上运行,而字符串的范围 API 将它们作为代码点运行,因此在混合数组操作和基于范围的字符串操作时必须小心。这也是为什么 stringwstring不被视为随机访问范围 - 只是双向范围。当代码点由不同数量的代码单元组成时,您不能在 O(1) 中对它们进行随机访问(而 dstring 是一个随机访问范围,因为对于 UTF-32,每个代码单元都是一个代码点)。

关于d - 如何逐个字符地读取字符串作为 D 中的范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16590650/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com