2014-05-30 78 views
7

我需要執行N次操作。 D做最好的方法是什麼?如何重複一次語句N次(簡單循環)

for(uint i=0; i<N; i++) 
    action(); 

foreach(uint i; 0.. N) 
    action(); 

也許更好?理想的情況是我想要的東西像Groovy的/ Ruby的times e.g

N.times { 
    action(); 
} 

這可能嗎?

+1

順便說一句,你的第二個例子中必須使用'foreach'而不是'for'實際上,你可以刪除'uint'。 D中用於循環迭代器的約定不需要在循環中引用,因此將其命名爲「_」。所以它變成了'foreach(_; 0 .. N)' – yaz

+0

我真的推薦下載免費的參考資料並閱讀它。所有這些在本書的早期就已經得到了回答。你的第一部作品。你的第二個是0..N {...}中的_。第三個是可能的,但我不確定時間延長是否正常。我知道在WWDC演示文稿中有這樣的例子,我認爲Swift入門。 –

回答

10

是的,這是可能的

import std.stdio; 
import std.traits; 

void foo() 
{ 
    writeln("Do It!"); 
} 

void times(T,N)(N n, T action) if (isCallable!T && isIntegral!N) 
{ 
    static if (ParameterTypeTuple!action.length == 1 
      && isIntegral!(ParameterTypeTuple!action[0])) 
     foreach (i; 0 .. n) 
      action(i); 
    else 
     foreach (i; 0 .. n) 
      action(); 
} 

void main(string[] args) 
{ 
    10.times(&foo); 
    10.times({writeln("Do It!");}); 
    10.times((uint n){writeln(n + 1, " Round");}); 
} 

版本的論證支持:

import std.stdio; 
import std.traits; 

void foo() 
{ 
    writeln("Do It!"); 
} 

struct Step { 
    alias n this; 
    size_t n; 
    this(size_t i) 
    { 
     n = i + 1; 
    } 
} 

struct Index { 
    alias n this; 
    size_t n; 
} 

void times(T,N,A...)(N n, T action, A args) if (isCallable!T && isIntegral!N) 
{ 
    alias PTTAction = ParameterTypeTuple!action; 
    static if (PTTAction.length >= 1) 
    { 
     alias FP = PTTAction[0]; 
     static if (is(Index == FP) || is(Step == FP)) 
      foreach (i; 0 .. n) 
       action(FP(i), args); 
     else 
      action(args); 
    } 
    else 
     foreach (i; 0 .. n) 
      action(); 
} 

void main(string[] args) 
{ 
    10.times(&foo); 
    10.times({writeln("Do It!");}); 
    10.times((Step n){writeln(n, " Step");}); 
    10.times((Index n, string msg){writeln(n, msg);}, " Index"); 
    stdin.readln; 
} 

UPDATE:

有更好的表現,你可以使用別名模板parametr行動:

void times(alias action,N)(N n) if (isCallable!action && isIntegral!N) 
{ 
    static if (ParameterTypeTuple!action.length == 1 
      && isIntegral!(ParameterTypeTuple!action[0])) 
     foreach (i; 0 .. n) 
      action(i); 
    else 
     foreach (i; 0 .. n) 
      action(); 
} 

void main(string[] args) 
{ 
    10.times!(foo); 
    10.times!({writeln("Do It!");}); 
    10.times!((uint n){writeln(n + 1, " Round");}); 
} 
+0

好的,謝謝:-)特別是第一個版本非常簡單,我很喜歡。 – Parobay

+0

你能寫出爲什麼表現可能會更好嗎? – Parobay

+0

由於按名稱傳遞(別名操作)不需要取消引用操作。但我不確定。也許有更多的原因,所以這將是interresing使這個單獨的問題。 – Kozzi11

4

也許這樣?

void loop(int n, void delegate() func) 
{ 
    foreach (i; 0 .. n) 
    { 
     func(); 
    } 
} 

用法:

loop(10, {   
    writeln("Hello World!"); 
});