Here is a simple generator in C#.
IEnumerable<int> Foo() { int a = 1, b = 1; while(true) { yield return b; int temp = a + b; a = b; b = temp; } }
How do I write a similar generator in Digital Mars D?
(The question is about the yield return statement)
Thanks!
Update. That's interesting. Since I'm just generating a mathematical sequence, using recurrence may be a good option.
auto fib = recurrence!("a[n-1] + a[n-2]")(1, 1); foreach (e; take(fib, 10)) // <- prints first ten numbers from the sequence { writeln(e); }
There's no exact equivalent in D. Here are some rough equivalents:
Using opApply-style internal iteration. This doesn't allow iterating over two iterators in lockstep, though:
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. } }
Use ranges. These are slightly harder to write in some cases, but are very efficient and allow lockstep iteration. This can also be iterated over with a foreach
loop, exactly like the opApply
version:
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; } }
If you really need coroutine-style stuff you can combine ranges and opApply together using core.thread.Fiber
, but you'll probably find that either ranges or opApply does what you need almost all the time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With