What is a “yield return” equivalent in the D programming language?

前端 未结 3 673
小鲜肉
小鲜肉 2021-02-01 17:11

Here is a simple generator in C#.

    IEnumerable Foo()
    {
        int a = 1, b = 1;
        while(true)
        {
            yield return b;
             


        
3条回答
  •  礼貌的吻别
    2021-02-01 17:39

    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.

提交回复
热议问题