Ответ 1
Нет точного эквивалента в D. Вот некоторые приблизительные эквиваленты:
Использование внутренней итерации стиля opApply. Это не позволяет выполнять итерацию по двум итераторам в режиме блокировки:
struct Foo {
int opApply(int delegate(ref int) dg) {
int a = 1, b = 1;
int result;
while(true) {
result = dg(b);
if(result) break;
int temp = a + b;
a = b;
b = temp;
}
return result;
}
}
void main() {
// Show usage:
Foo foo;
foreach(elem; foo) {
// Do stuff.
}
}
Использовать диапазоны. В некоторых случаях их немного сложнее записать, но они очень эффективны и позволяют выполнять итерацию блокировки. Это также можно повторить с помощью цикла foreach
, точно так же, как версия opApply
:
struct Foo {
int a = 1, b = 1;
int front() @property {
return b;
}
void popFront() {
int temp = a + b;
a = b;
b = temp;
}
// This range is infinite, i.e. never empty.
enum bool empty = false;
typeof(this) save() @property { return this; }
}
Если вы действительно нуждаетесь в стиле coroutine, вы можете комбинировать диапазоны и opApply вместе, используя core.thread.Fiber
, но вы, вероятно, обнаружите, что либо диапазоны, либо opApply делает то, что вам нужно почти все время.