Frage

C# verfügt über Generatorfunktionen mit folgender Syntax:

IEnumerable<int> GetNats(int max)
{
   for (int i=0; i < max; ++i)
      yield return i;
}

Eine Funktion, die mich für meine Programmiersprache (eine einfache objektorientierte Programmierung ähnlich Java, Scala, ActionScript und C#) interessiert, sind Generatorausdrücke.Dabei handelt es sich im Wesentlichen um syntaktischen Zucker für Generatorfunktionen.

Mein aktueller Lieblingskandidat ist die folgende Syntax:

IEnumerable<int> nats = 
  witheach (i in range(0, 42)) 
     yield i * 2; 

Der Ausdruck range(0, 42) ist eine eingebaute Generatorfunktion.

Meine Frage ist also, welche Syntax würden Sie für Generatorausdrücke in einer Sprache vom Typ C#/Java/Scala/ActionScript bevorzugen und warum?

Einige Faktoren, die Antworten beeinflussen können, sind, dass Typen in meiner Sprache wie Scala und ActionScript nach dem Typ deklariert werden.Zum Beispiel:

var myVar : SomeType = initialValue;

Auch anonyme Funktionen sehen so aus:

var myFunc = function(int x) { 
  return x + 1; 
}

Ansonsten ähnelt der Rest meiner Sprachsyntax Java oder C#.Meine Sprache hat eine foreach Anweisung, die C# sehr ähnlich ist.

War es hilfreich?

Lösung

Es gibt auch Pythons Ansatz – keine spezielle Syntax für Generatoren;Das Vorhandensein einer „Yield“-Anweisung genügt.Alle Anweisungen, die einen Block benötigen, könnten verwendet werden, obwohl ich erwarte, dass in der Praxis nur Schleifen verwendet werden:

IEnumerable<int> nats = 
    for (i in range(0,42))
        yield i*2

String phrase = "I want to buy some cheese.";
IEnumerable<int> substrs =
    for (i in 0 .. phrase.length)
        for (j in i .. phrase.length+1)
            yield phrase[i..j]

Hier gehe ich davon aus, dass der richtige Endpunkt nicht in einem Bereich enthalten ist.

Um ganz ehrlich zu sein, als ich das in Python sah, musste ich mich fragen:"Zu welchem ​​Preis?"

Andere Tipps

Schauen Sie sich an, was F# tut. Du kannst tun

seq { seq-expr }    // IEnumerable<T>, a.k.a. seq<T>
[ seq-expr ]        // list<T>
[| seq-expr |]      // array<T>

wobei SEQ-EXPR ein Formular ist, das die meisten Sprachkonstrukte zusammen mit "Ertrag" enthält. Also zB du kannst schreiben

seq {
    for i in 0..9 do
        for j in someColl do
            if i <> j then
                yield i*j
}

Der F# Compiler übersetzt diesen Code in eine Implementierung von IEnumerable (wie C# für Iteratorblöcke).

Ich mag diese Syntax, weil es bedeutet, dass Sie genau denselben Code schreiben können, den Sie schreiben würden, um "jetzt imperativen Zeug zu tun", z. B.

    for i in 0..9 do
        for j in someColl do
            if i <> j then
                printfn "%d" i*j

Wickeln Sie diesen Code jedoch in SEQ {} ein und verwenden Sie stattdessen 'Ertrag' und der Code wird zu einer faulen Ienumerable.

IEnumerable nats = 0...42

or for generators 

IEnumerable nats = yield 0...42
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top