2012-08-26 5 views
8

Ich kann nicht eine gute Möglichkeit, die folgenden in Xtend auszudrücken, ohne auf einer while-Schleife zu finden scheinen:XTend For-Schleife Unterstützung und Range-Support Hinzufügen

for(int i = 0; i < 3; i++){ 
    println("row "); 
} 
println("your boat"); 

Also, ich denke, meine Frage zwei hat Teile:

  • Gibt es einen besseren Weg, um das oben genannte zu tun? Ich sah nichts vielversprechendes in ihrem documenation
  • Ein großer Teil der Funktionen, die die Sprache hat, sind nur Xtend Bibliothekserweiterungen (und sie sind großartig!). Gibt es range() Funktionalität à la Python, von der ich nichts weiß?

Ich landete mein eigenes Aufrollen und bekam etwas wie folgt aus:

class LanguageUtil { 

def static Iterable<Integer> range(int stop) { 
    range(0, stop) 
} 

def static Iterable<Integer> range(int start, int stop) { 
    new RangeIterable(start, stop, 1) 
} 

def static Iterable<Integer> range(int start, int stop, int step) { 
    new RangeIterable(start, stop, step) 
} 
} 

// implements Iterator and Iterable which is bad form. 
class RangeIterable implements Iterator<Integer>, Iterable<Integer> { 
val int start 
val int stop 
val int step 
var int current 

new(int start, int stop, int step) { 
    this.start = start; 
    this.stop = stop; 
    this.step = step 
    this.current = start 
} 

override hasNext() { 
    current < stop 
} 

override next() { 
    val ret = current 
    current = current + step 
    ret 
} 

override remove() { 
    throw new UnsupportedOperationException("Auto-generated function stub") 
} 

/** 
* This is bad form. We could return a 
* new RangeIterable here, but that seems worse. 
*/ 
override iterator() { 
    this 
} 
} 

Antwort

15

Die genaue Ersatz für

for(int i = 0; i < 3; i++){ 
    println("row "); 
} 

ist

for (i : 0 ..< 3) { 
    println("row ") 
} 

Beachten Sie die exklusive Auswahl Betreiber: ..<

4

Heh, fand ich die Antwort ein wenig später:

for(i: 1..3) { 
    println("row ") 
} 
+0

Sie sogar vermeiden kann schreiben 'Integer' weil sie von Xtend automagically abgeleitet. –

13

Auch können Sie es tun idiomatisch mit

(1..3).forEach[println("row")] 

Sehr neu zu Xtend aber Mann es m akes Programmierung auf dem jvm genial.

+0

Beachten Sie, dass Sie innerhalb des Lambda-Ausdrucks [] eine Einschränkung haben. Wenn Sie beispielsweise auf eine lokale Variable localVar innerhalb dieses Ausdrucks zugreifen möchten, erhalten Sie "Kann nicht auf die nicht endgültige Variable localVar innerhalb eines Lambda-Ausdrucks verweisen". Ich finde die Antwort von rzymek auf die Frage des ursprünglichen Posters vollständiger. – CuongHuyTo

+0

sehen Sie meine Antwort unten, wenn Sie auch den Iterationsindex innerhalb der Funktion benötigen –

5

Für mich eine bereichsbasierte forEach impliziert der Bereich irgendwie sinnvoll ist. Für Looping eine bestimmte Anzahl von Zeiten ohne Iterationsvariable, finde ich Rubys times Schleife die Absicht deutlicher zum Ausdruck bringt: es ist kein Teil von IntegerExtensions, aber die Umsetzung ist trivial

3.times [|println("row")] 

Leider:

def static times(int iterations, Runnable runnable) { 
    if (iterations < 0) throw new IllegalArgumentException(
      '''Can't iterate negative («iterations») times.''') 
    for (i: 0 ..< iterations) runnable.run() 
} 
+0

Dies wurde vorgeschlagen, um die Kern-Xtend-Bibliothek in https://bugs.eclipse.org/bugs/show_bug.cgi?id=489944 hinzugefügt werden – vorburger

3

Seit unterstützen wir auch die "traditionelle" for-Schleife, genau wie in Java.

3

Es gibt tatsächlich eine Version von forEach(), die ein Lambda mit zwei Parametern akzeptiert. Es ist nützlich, wenn Sie innerhalb der Schleife auf den Iterationsindex zugreifen müssen.

(10..12).forEach[ x, i | println('''element=«x» index=«i»''')] 

druckt:

element=10 index=0 
element=11 index=1 
element=12 index=2 
Verwandte Themen