2010-06-15 63 views
7

如何使一個類在foreach語句中可用?如何在D中創建一個對象(類)?

該類包含一個關聯數組(例如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; 
} 

同樣是公衆詮釋opApply(INT委託(REF類型)DG)來完成。

回答

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和類對象可以與範圍來完成,這意味着[一組]屬性必須被定義:

+2

我不認爲基於範圍-的foreach支持開箱呢。而且「opApply」也可以在D2中使用。 – kennytm 2010-06-15 15:58:10

+0

opApply是解決方案,thnx! – VDVLeon 2010-06-15 16:11:32

2

由OP發佈的解決方案是一個有效的解決方案,但在D2中有另一個解決方案。 D中的迭代可以分爲由opApply處理的內部迭代和由範圍處理的外部迭代。

內部迭代使對象在調用堆棧的控制上迭代。例如,這允許被迭代的對象使用遞歸而不用維護顯式堆棧,但是使得以鎖步形式迭代多個結構成爲不可能。外部迭代恰恰相反。

通過範圍完成外部迭代。範圍是定義三種方法的任何類或結構:front()提供對範圍中第一個元素的訪問權限,popFront()提高範圍,empty()返回true,如果範圍爲空。如果範圍是無限的,則可以將空聲明爲常數而不是成員函數。通過這種方式,調用者可以控制調用堆棧,這是一種根據情況可以是好還是壞的折衷。

下面是一個使用範圍的例子迭代:

/**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; 
} 
+0

那麼,根據Range原語是否存在針對'foreach(key,value; collection)'的編譯器重寫?我還沒有看到任何東西,我只是希望:D – Tim 2012-06-26 22:49:05