用字符串迭代数组

时间:2014-01-20 00:29:25

标签: d

import std.stdio, std.string, std.conv, std.array;
int main(){
foreach(int i,s; splitter("Hello world !")){
    writeln(i);
    };
    return 0;
}

大家好! 我想在数组和字符串中获取字符串索引。 为什么我会收到此错误?

dmd main.d
Error: cannot infer argument types
make: *** [c] Error 1

2 个答案:

答案 0 :(得分:1)

这是范围模型的限制:foreach over range给出当前项,但不是当前索引。最简单的修复方法是使用std.string / std.array中的split(它急切地分配一个新数组来保存结果并返回结果)或者只是将数量保存在外部变量中:

int i;
foreach(s; splitter("whatever")) {
   // use s and i
   i++;
}

虽然注意到从分割器返回的范围无论如何都无法编入索引... splitter("whatever")[0]将无法编译。分割器工作的方式是它只在需要时找到下一个分割点,并且它一次只能执行那个分割点,因为它涉及扫描字符串。作为一般规则,范围不喜欢在其方法中使用循环 - 因此用户可以轻松看到速度复杂性 - 并且扫描字符串当然需要循环。

索引也许可以自动保存,但语言根本就不会这样做。通过一些自定义foreach操作,它会调用您定义的函数:

int opApply(int delegate(int idx, string s) dg);

在那里,你可以foreach(i, s) {},它会从opApply定义中找出来。但是对于范围,它会这样做:

for(auto f = range.front; !range.empty; range.popFront())

没有空间来定义第二个索引变量,也没有自动插入。这可能会在某些时候发生变化,但它究竟会如何发展,并且没有特别急于在社区中做到这一点 - 添加你自己的int计数器变量很容易,这个限制并不是一个很大的障碍虽然它有时让我们中的一些人烦恼。

答案 1 :(得分:1)

将来(https://github.com/D-Programming-Language/phobos/pull/1866)您将能够使用此代码:

import std.range: enumerate;

foreach(i, s; splitter("Hello world !").enumerate){
    writeln(i);
}