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
答案 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);
}