Freigeben über


Funktionen

Eine Funktion ist ein Wert, der eine Zuordnung mehrerer Argumentwerte zu einem einzelnen Wert darstellt. Eine Funktion wird aufgerufen, indem eine Reihe von Eingabewerten (Argumentwerte) bereitgestellt wird und ein einzelner Ausgabewert (der Rückgabewert) erzeugt wird.

Schreiben von Funktionen

Funktionen werden mithilfe eines Funktionsausdrucks geschrieben:

Funktionsausdruck:
      (parameter-listopt)function-return-typeopt=>function-body
function-body:
      expression
parameter-list:
      fixed-parameter-list
      fixed-parameter-list
,optional-parameter-list
      optional-parameter-list
fixed-parameter-list:
      parameter
      parameter
,fixed-parameter-list
:
      parameter-name parameter-typeopt
parameter-name:
      Bezeichner
parameter-type:
      assertion
function-return-type:
      assertion
assertion:

      asnullable-primiitve-type
optional-parameter-list:
      optional-parameter
      optional-parameter
,optional-parameter-list
optional-parameter:

      optionalparameter
nullable-primitve-type
      nullable
optprimitive-type

Im Folgenden finden Sie ein Beispiel für eine Funktion, für die genau zwei Werte erforderlich sind (x und y) und die das Ergebnis der Anwendung des +-Operators auf diese Werte erzeugt. x und y sind Parameter, die Teil der Parameterliste der Funktion sind, und x + y ist der Funktionstext:

(x, y) => x + y

Das Ergebnis der Auswertung eines Funktionsausdrucks besteht darin, einen Funktionswert zu erstellen (nicht zum Auswerten des Funktionstexts). Als Konvention werden Funktionswerte in diesem Dokument (im Gegensatz zu Funktionsausdrücken) zwar mit der Parameterliste, allerdings mit Auslassungspunkten (...) anstelle des Funktionstexts angezeigt. Wenn z. B. der obige Funktionsausdruck ausgewertet wurde, wird er als folgender Funktionswert angezeigt:

 (x, y) => ...

Die folgenden Operatoren sind für Funktionswerte definiert:

Operator Ergebnis
x = y Gleich
x <> y Ungleich

Der native Typ von Funktionswerten ist ein benutzerdefinierter Funktionstyp (abgeleitet vom intrinsischen Typ function), der die Parameternamen auflistet und alle Parametertypen und den Rückgabetyp angibt, der any sein soll. (Wechseln Sie zu Funktionstypen, um weitere Informationen zu erhalten.)

Aufrufen von Funktionen

Der Funktionstext einer Funktion wird durch Aufrufen des Funktionswerts mithilfe eines Aufrufausdrucks ausgeführt. Das Aufrufen eines Funktionswerts bedeutet, dass der Funktionstext des Funktionswerts ausgewertet wird und ein Wert zurückgegeben oder ein Fehler ausgelöst wird.

invoke-expression:
      primary-expression
(argument-listopt)
argument-list:
      expression-list

Jedes Mal, wenn ein Funktionswert aufgerufen wird, werden mehrere Werte als Argumentliste angegeben, die als Argumente der Funktion bezeichnet werden.

Eine Argumentliste wird verwendet, um eine festgelegte Anzahl von Argumenten direkt als Liste von Ausdrücken anzugeben. Im folgenden Beispiel wird ein Datensatz mit einem Funktionswert in einem Feld definiert und anschließend die Funktion aus einem anderen Feld des Datensatzes aufgerufen:

[ 
    MyFunction = (x, y, z) => x + y + z, 
    Result1 = MyFunction(1, 2, 3)           // 6
]

Beim Aufrufen einer Funktion gilt Folgendes:

  • Die Umgebung, die zum Auswerten des Funktionstexts der Funktion verwendet wird, enthält eine Variable, die den einzelnen Parametern mit dem gleichen Namen wie der Parameter entspricht. Der Wert jedes Parameters entspricht einem Wert, der wie in Parameter definiert aus der Argumentliste des Abrufausdrucks erstellt wurde.

  • Alle Ausdrücke, die den Funktionsargumenten entsprechen, werden vor dem Funktionstext ausgewertet.

  • Fehler, die beim Auswerten der Ausdrücke in der Ausdrucksliste oder dem Funktionstext ausgelöst werden, werden weitergegeben.

  • Die Anzahl der aus der Argumentlist erstellten Argumente muss mit den Parametern der Funktion übereinstimmen. Andernfalls wird ein Fehler mit dem Ursachencode "Expression.Error" ausgelöst. Der Prozess zum Ermitteln der Kompatibilität wird in Parameter definiert.

Parameter

Es gibt zwei Arten von Parametern, die in einer Parameterliste enthalten sein können:

  • Ein erforderlicher Parameter gibt an, dass ein Argument, das dem Parameter entspricht, immer angegeben werden muss, wenn eine Funktion aufgerufen wird. Erforderliche Parameter müssen zuerst in der Parameterliste angegeben werden. Die Funktion im folgenden Beispiel definiert die erforderlichen Parameter x und y:

      [ 
          MyFunction = (x, y) => x + y, 
    
          Result1 = MyFunction(1, 1),     // 2 
          Result2 = MyFunction(2, 2)      // 4
      ] 
    
  • Ein optionaler Parameter gibt an, dass ein Argument, das dem Parameter entspricht, ggf. angegeben werden kann, wenn eine Funktion aufgerufen wird. Wenn ein Argument, das einem optionalen Parameter entspricht, beim Aufrufen der Funktion nicht angegeben wird, wird stattdessen der Wert null verwendet. Optionale Parameter müssen nach allen erforderlichen Parametern in einer Parameterliste angezeigt werden. Die Funktion im folgenden Beispiel definiert den unveränderlichen Parameter x und den optionalen Parameter y:

      [ 
          MyFunction = (x, optional y) =>
                            if (y = null) x else x + y, 
          Result1 = MyFunction(1),        // 1 
          Result2 = MyFunction(1, null),  // 1 
          Result3 = MyFunction(2, 2),     // 4
      ] 
    

Die Anzahl der Argumente, die angegeben werden, wenn eine Funktion aufgerufen wird, muss mit der Parameterliste übereinstimmen. Die Kompatibilität der Argumente A für eine Funktion F wird wie folgt berechnet:

  • Der Wert N soll die Anzahl der Argumente darstellen, die A aus der Argumentliste erstellt hat. Beispiel:

      MyFunction()             // N = 0 
      MyFunction(1)            // N = 1 
      MyFunction(null)         // N = 1 
      MyFunction(null, 2)      // N = 2 
      MyFunction(1, 2, 3)      // N = 3 
      MyFunction(1, 2, null)   // N = 3 
      MyFunction(1, 2, {3, 4}) // N = 3
    
  • Der Wert Required (Erforderlich) soll die Anzahl unveränderlicher Parameter von F und Optional die Anzahl der optionalen Parameter von F darstellen. Beispiel:

    ()               // Required = 0, Optional = 0 
    (x)              // Required = 1, Optional = 0 
    (optional x)     // Required = 0, Optional = 1 
    (x, optional y)  // Required = 1, Optional = 1
    
  • Die Argumente A stimmen mit der Funktion F überein, wenn Folgendes zutrifft:

    • (N >= Fixed) and (N <= (Fixed + Optional))
    • Die Argumenttypen stimmen mit den entsprechenden Parametertypen von F überein.
  • Wenn die Funktion über einen deklarierten Rückgabetyp verfügt, stimmt der Ergebniswert des Funktionstexts von F mit dem Rückgabetyp von F überein, wenn Folgendes zutrifft:

    • Der Wert, der durch Auswerten des Funktionstexts mit den bereitgestellten Argumenten für die Funktionsparameter ausgegeben wird, verfügt über einen Typ, der mit dem Rückgabetyp kompatibel ist.
  • Wenn der Funktionstext einen Wert ausgibt, der nicht mit dem Rückgabetyp der Funktion kompatibel ist, wird ein Fehler mit dem Ursachencode "Expression.Error" ausgelöst.

Rekursive Funktionen

Der Bereichsoperator (@) muss zum Schreiben eines rekursiven Funktionswerts verwendet werden, damit innerhalb des Gültigkeitsbereichs auf die Funktion verwiesen wird. Der folgende Datensatz enthält z. B. ein Feld, das die Factorial-Funktion definiert, und ein weiteres Feld, das es aufruft:

[ 
    Factorial = (x) => 
                if x = 0 then 1 else x * @Factorial(x - 1), 
    Result = Factorial(3)  // 6 
]

Ebenso können wechselseitig rekursive Funktionen geschrieben werden, solange jede Funktion, auf die zugegriffen werden muss, einen Namen hat. Im folgenden Beispiel wurde ein Teil der Factorial-Funktion in eine zweite Factorial2-Funktion umgestaltet.

[ 
    Factorial = (x) => if x = 0 then 1 else Factorial2(x), 
    Factorial2 = (x) => x * Factorial(x - 1), 
    Result = Factorial(3)     // 6 
]

Abschlüsse

Eine Funktion kann eine andere Funktion als Wert zurückgeben. Diese Funktion kann wiederum von einem oder mehreren Parametern der ursprünglichen Funktion abhängen. Im folgenden Beispiel gibt die Funktion, die dem MyFunction-Feld zugeordnet ist, eine Funktion zurück, die den für sie selbst angegebenen Parameter zurückgibt:

[ 
    MyFunction = (x) => () => x, 
    MyFunction1 = MyFunction(1), 
    MyFunction2 = MyFunction(2), 
    Result = MyFunction1() + MyFunction2()  // 3 
]

Jedes Mal, wenn die Funktion aufgerufen wird, wird ein neuer Funktionswert zurückgegeben, der den Parameterwert beibehält, sodass bei jedem Aufruf der Parameterwert zurückgegeben wird.

Funktionen und Umgebungen

Zusätzlich zu den Parametern kann der Funktionstext eines Funktionsausdrucks auf Variablen verweisen, die in der Umgebung vorhanden sind, wenn die Funktion initialisiert wird. Beispielsweise greift die durch das Feld MyFunction definierte Funktion auf das Feld C des einschließenden Datensatzes A zu:

[ 
A =  
    [ 
        MyFunction = () => C, 
        C = 1 
    ], 
B = A[MyFunction]()           // 1 
]

Wenn MyFunction aufgerufen wird, greift das Feld auf den Wert der Variable C zu, obwohl es aus einer Umgebung (B) aufgerufen wird, die keine Variable C enthält.

Vereinfachte Deklarationen

Der each-Ausdruck ist eine syntaktische Kurzform zum Deklarieren nicht typisierter Funktionen, die einen einzelnen Parameter namens _ annehmen (Unterstrich).

each-Ausdruck:
      eacheach-expression-body
each-expression-body:
      function-body

Vereinfachte Deklarationen werden häufig verwendet, um die Lesbarkeit von Funktionsaufrufen höherer Ordnung zu verbessern.

Beispielsweise sind die folgenden Deklarationspaare semantisch äquivalent:

each _ + 1 
(_) => _ + 1  
each [A] 
(_) => _[A] 
 
Table.SelectRows( aTable, each [Weight] > 12 ) 
Table.SelectRows( aTable, (_) => _[Weight] > 12 )