如何在D中使对象(类)可以放置?

时间:2010-06-15 15:24:51

标签: foreach d associative-array

如何在foreach语句中创建一个类?

该类包含一个关联数组(例如string [string])。所以foreach语句使用这个数组作为源。

所以这就是我想要的:

auto obj = new Obj();
foreach (key, value; obj)
{
    ...
}

我是否需要实现类似的接口?

编辑:

解决方案:

public int opApply(int delegate(ref string, ref Type) dg)
{
    int result = 0;

    foreach (ref key, ref value; data)
    {
        result = dg(key, value);
        if (result != 0)
        {
            break;
        }
    }

    return result;
}

对于public int opApply(int delegate(ref Type)dg)也是如此。

2 个答案:

答案 0 :(得分:4)

D1

class Foo
{
    uint array[2];

    int opApply(int delegate(ref uint) dg)
    {
        int result = 0;

        for (int i = 0; i < array.length; i++)
        {
            result = dg(array[i]);
            if (result)
                break;
        }
        return result;
    }
}

D2

  

对struct和class对象的迭代可以用范围完成,这意味着必须定义[一组]属性:

答案 1 :(得分:3)

OP发布的解决方案是一种有效的解决方案,但在D2中,另一种解决方案具有不同的权衡。 D中的迭代可以分为内部迭代(由opApply处理)和外部迭代(由范围处理)。

内部迭代使对象通过调用堆栈的控制进行迭代。例如,这允许被迭代的对象使用递归而不保持显式堆栈,但是不可能以锁步方式迭代多个结构。外部迭代正好相反。

外部迭代通过范围完成。范围是定义三种方法的任何类或结构:front()允许访问范围中的第一个元素,popFront()使范围前进,empty()返回true如果范围是空的。如果范围是无穷大,则可以将empty声明为常量而不是成员函数。通过这种方式,调用者可以控制调用堆栈,这取决于具体情况,这可能是好的或坏的。

以下是使用迭代范围的示例:

/**This struct lazily produces all Fibonacci numbers.*/
struct Fibonacci {
    ulong num1 = 0;
    ulong num2 = 1;

    ulong front() {
        return num1 + num2;
    }

    void popFront() {
        auto newNum2 = num1 + num2;
        num1 = num2;
        num2 = newNum2;
    }

    // A range of Fibonacci numbers is infinite.
    enum bool empty = false; 
}