Funktionsliterale
Alle Funktionen werden mit einem Funktionsausdruck erstellt. Eine einfache Funktion wird mit dem Pfeil -> notiert.
my_function = ->my_function() -- leere Funktion aufrufenmy_function = ->my_function() -- leere Funktion aufrufenDer Funktionskörper kann entweder eine einzelne Anweisung direkt nach dem Pfeil sein oder aus mehreren Anweisungen bestehen, die in den folgenden Zeilen eingerückt werden:
func_a = -> print "Hallo Welt"
func_b = -> value = 100 print "Der Wert:", valuefunc_a = -> print "Hallo Welt"
func_b = -> value = 100 print "Der Wert:", valueWenn eine Funktion keine Argumente hat, kann sie mit dem !-Operator statt leerer Klammern aufgerufen werden. Der !-Aufruf ist die bevorzugte Art, Funktionen ohne Argumente aufzurufen.
func_a!func_b()func_a!func_b()Funktionen mit Argumenten werden erstellt, indem der Pfeil von einer Argumentliste in Klammern eingeleitet wird:
sum = (x, y) -> print "Summe", x + ysum = (x, y) -> print "Summe", x + yFunktionen können aufgerufen werden, indem die Argumente hinter dem Namen eines Ausdrucks stehen, der zu einer Funktion evaluiert. Beim Verketten mehrerer Funktionsaufrufe werden die Argumente der nächstliegenden Funktion links zugeordnet.
sum 10, 20print sum 10, 20
a b c "a", "b", "c"sum 10, 20print sum 10, 20
a b c "a", "b", "c"Um Mehrdeutigkeiten beim Aufruf zu vermeiden, können die Argumente auch in Klammern gesetzt werden. Das ist hier nötig, damit die richtigen Argumente an die richtigen Funktionen gehen.
print "x:", sum(10, 20), "y:", sum(30, 40)print "x:", sum(10, 20), "y:", sum(30, 40)Zwischen öffnender Klammer und Funktionsname darf kein Leerzeichen stehen.
Funktionen wandeln die letzte Anweisung im Funktionskörper in ein return um. Das nennt sich implizites Return:
sum = (x, y) -> x + yprint "Die Summe ist ", sum 10, 20sum = (x, y) -> x + yprint "Die Summe ist ", sum 10, 20Wenn du explizit zurückgeben willst, verwende return:
sum = (x, y) -> return x + ysum = (x, y) -> return x + yWie in Lua können Funktionen mehrere Werte zurückgeben. Die letzte Anweisung muss eine Liste von Werten sein, getrennt durch Kommas:
mystery = (x, y) -> x + y, x - ya, b = mystery 10, 20mystery = (x, y) -> x + y, x - ya, b = mystery 10, 20Fat Arrows
Abschnitt betitelt „Fat Arrows“Da es in Lua üblich ist, beim Methodenaufruf ein Objekt als erstes Argument zu übergeben, gibt es eine spezielle Syntax zum Erstellen von Funktionen, die automatisch ein self-Argument enthalten.
func = (num) => @value + numfunc = (num) => @value + numStandardwerte für Argumente
Abschnitt betitelt „Standardwerte für Argumente“Es ist möglich, Standardwerte für Funktionsargumente anzugeben. Ein Argument gilt als leer, wenn sein Wert nil ist. Alle nil-Argumente mit Standardwert werden vor Ausführung des Funktionskörpers ersetzt.
my_function = (name = "etwas", height = 100) -> print "Hallo, ich bin", name print "Meine Größe ist", heightmy_function = (name = "etwas", height = 100) -> print "Hallo, ich bin", name print "Meine Größe ist", heightDer Ausdruck für den Standardwert wird im Funktionskörper in der Reihenfolge der Argumentdeklarationen ausgewertet. Daher können Standardwerte auf zuvor deklarierte Argumente zugreifen.
some_args = (x = 100, y = x + 1000) -> print x + ysome_args = (x = 100, y = x + 1000) -> print x + yHinweise
Abschnitt betitelt „Hinweise“Aufgrund der ausdrucksstarken, klammerlosen Funktionsaufrufe müssen einige Einschränkungen gelten, um Parsing-Mehrdeutigkeiten mit Leerraum zu vermeiden.
Das Minuszeichen hat zwei Rollen: unäre Negation und binäre Subtraktion. Sieh dir an, wie die folgenden Beispiele kompiliert werden:
a = x - 10b = x-10c = x -yd = x- za = x - 10b = x-10c = x -yd = x- zDie Präzedenz des ersten Arguments eines Funktionsaufrufs kann mit Leerraum gesteuert werden, wenn das Argument ein String-Literal ist. In Lua lässt man bei Aufrufen mit einem einzelnen String- oder Tabellenliteral häufig die Klammern weg.
Wenn kein Leerzeichen zwischen Variable und String-Literal steht, hat der Funktionsaufruf Vorrang vor nachfolgenden Ausdrücken. In dieser Form können keine weiteren Argumente übergeben werden.
Steht ein Leerzeichen zwischen Variable und String-Literal, verhält sich der Aufruf wie oben gezeigt. Das String-Literal gehört dann zu nachfolgenden Ausdrücken (falls vorhanden) und dient als Argumentliste.
x = func"hallo" + 100y = func "hallo" + 100x = func"hallo" + 100y = func "hallo" + 100Mehrzeilige Argumente
Abschnitt betitelt „Mehrzeilige Argumente“Wenn Funktionsaufrufe viele Argumente haben, ist es praktisch, die Argumentliste auf mehrere Zeilen zu verteilen. Wegen der whitespace-sensitiven Natur der Sprache muss man dabei sorgfältig sein.
Wenn eine Argumentliste in der nächsten Zeile fortgesetzt wird, muss die aktuelle Zeile mit einem Komma enden. Die folgende Zeile muss stärker eingerückt sein als die aktuelle. Sobald eingerückt, müssen alle weiteren Argumentzeilen auf derselben Einrückungsebene liegen, um Teil der Argumentliste zu sein.
my_func 5, 4, 3, 8, 9, 10
cool_func 1, 2, 3, 4, 5, 6, 7, 8my_func 5, 4, 3, 8, 9, 10
cool_func 1, 2, 3, 4, 5, 6, 7, 8Diese Art des Aufrufs kann verschachtelt werden. Die Einrückungsebene bestimmt, zu welcher Funktion die Argumente gehören.
my_func 5, 6, 7, 6, another_func 6, 7, 8, 9, 1, 2, 5, 4my_func 5, 6, 7, 6, another_func 6, 7, 8, 9, 1, 2, 5, 4Da Tabellen ebenfalls das Komma als Trennzeichen verwenden, hilft diese Einrückungssyntax dabei, Werte zur Argumentliste gehören zu lassen, statt zur Tabelle.
x = [ 1, 2, 3, 4, a_func 4, 5, 5, 6, 8, 9, 10]x = [ 1, 2, 3, 4, a_func 4, 5, 5, 6, 8, 9, 10]Obwohl es selten ist: Du kannst Funktionsargumente tiefer einrücken, wenn du weißt, dass du später eine geringere Einrückungsebene verwenden wirst.
y = [ my_func 1, 2, 3, 4, 5, 5, 6, 7]y = [ my_func 1, 2, 3, 4, 5, 5, 6, 7]Dasselbe lässt sich mit anderen Block-Statements wie Bedingungen machen. Wir können die Einrückungsebene verwenden, um zu bestimmen, zu welcher Anweisung ein Wert gehört:
if func 1, 2, 3, "hallo", "Welt" print "hallo" print "Ich bin innerhalb der if-Bedingung"
if func 1, 2, 3, "hallo", "Welt" print "hallo" print "Ich bin innerhalb der if-Bedingung"if func 1, 2, 3, "hallo", "Welt" print "hallo" print "Ich bin innerhalb der if-Bedingung"
if func 1, 2, 3, "hallo", "Welt" print "hallo" print "Ich bin innerhalb der if-Bedingung"Parameter-Destructuring
Abschnitt betitelt „Parameter-Destructuring“YueScript unterstützt jetzt Destructuring von Funktionsparametern, wenn das Argument ein Objekt ist. Es gibt zwei Formen von Destructuring-Tabellenliteralen:
- Geschweifte Klammern/Objektparameter, die optionale Standardwerte erlauben, wenn Felder fehlen (z. B.
{:a, :b},{a: a1 = 123}). - Unverpackte einfache Tabellensyntax, die mit einer Sequenz aus Key-Value- oder Shorthand-Bindings beginnt und so lange läuft, bis ein anderer Ausdruck sie beendet (z. B.
:a, b: b1, :c). Diese Form extrahiert mehrere Felder aus demselben Objekt.
f1 = (:a, :b, :c) -> print a, b, c
f1 a: 1, b: "2", c: {}
f2 = ({a: a1 = 123, :b = 'abc'}, c = {}) -> print a1, b, c
arg1 = {a: 0}f2 arg1, arg2f1 = (:a, :b, :c) -> print a, b, c
f1 a: 1, b: "2", c: {}
f2 = ({a: a1 = 123, :b = 'abc'}, c = {}) ->print a1, b, c
arg1 = {a: 0}f2 arg1, arg2Präfixiertes Return-Expression
Abschnitt betitelt „Präfixiertes Return-Expression“Wenn du mit tief verschachtelten Funktionskörpern arbeitest, kann es mühsam sein, die Lesbarkeit und Konsistenz des Rückgabewerts zu erhalten. Dafür führt YueScript die Syntax der präfixierten Return-Expression ein. Sie hat folgende Form:
findFirstEven = (list): nil -> for item in *list if type(item) == "table" for sub in *item if sub % 2 == 0 return subfindFirstEven = (list): nil -> for item in *list if type(item) == "table" for sub in *item if sub % 2 == 0 return subDas ist äquivalent zu:
findFirstEven = (list) -> for item in *list if type(item) == "table" for sub in *item if sub % 2 == 0 return sub nilfindFirstEven = (list) -> for item in *list if type(item) == "table" for sub in *item if sub % 2 == 0 return sub nilDer einzige Unterschied ist, dass du den finalen Rückgabeausdruck vor das ->- oder =>-Token ziehen kannst, um den impliziten Rückgabewert der Funktion als letzte Anweisung zu kennzeichnen. So musst du selbst bei Funktionen mit mehreren verschachtelten Schleifen oder bedingten Zweigen kein abschließendes return am Ende des Funktionskörpers mehr schreiben, was die Logikstruktur klarer und leichter nachvollziehbar macht.
Benannte Varargs
Abschnitt betitelt „Benannte Varargs“Mit der Syntax (...t) -> kannst du Varargs automatisch in einer benannten Tabelle speichern. Diese Tabelle enthält alle übergebenen Argumente (einschließlich nil-Werten), und das Feld n der Tabelle speichert die tatsächliche Anzahl übergebener Argumente (einschließlich nil-Werten).
f = (...t) -> print "Anzahl der Argumente:", t.n print "Tabellenlänge:", #t for i = 1, t.n print t[i]
f 1, 2, 3f "a", "b", "c", "d"f!
-- Fälle mit nil-Werten behandelnprocess = (...args) -> sum = 0 for i = 1, args.n if args[i] != nil and type(args[i]) == "number" sum += args[i] sum
process 1, nil, 3, nil, 5f = (...t) -> print "Anzahl der Argumente:", t.n print "Tabellenlänge:", #t for i = 1, t.n print t[i]
f 1, 2, 3f "a", "b", "c", "d"f!
-- Fälle mit nil-Werten behandelnprocess = (...args) -> sum = 0 for i = 1, args.n if args[i] != nil and type(args[i]) == "number" sum += args[i] sum
process 1, nil, 3, nil, 5