Dela via


Funktioner

En funktion är ett värde som representerar en mappning från en uppsättning argumentvärden till ett enda värde. En funktion anropas av en uppsättning indatavärden (argumentvärdena) och skapar ett enda utdatavärde (returvärdet).

Skriva funktioner

Funktioner skrivs med ett funktionsuttryck:

function-expression:
      ( parameter-listopt)function-return-typeopt=>function-body
function-body:
      uttryck
parameter-list:
      fixed-parameter-list
      fixed-parameter-list
, optional-parameter-list
      optional-parameter-list
fixed-parameter-list:
      parameter
      parametern
, fixed-parameter-list
parameter:
      parameter-name parameter-typeopt
parameter-name:
      identifierare
parametertyp:
      assertion
function-return-type:
      assertion
påstående:

      as nullable-primiitve-type
optional-parameter-list:
      optional-parameter
      optional-parameter
, optional-parameter-list
optional-parameter:

      optionalparameter
nullable-primitve-type
      nullable
opt primitive-type

Följande är ett exempel på en funktion som kräver exakt två värden x och y, och ger resultatet av att tillämpa operatorn på + dessa värden. och x är parametrar som ingår i parameterlistan för funktionen och är funktionstextenx + y: y

(x, y) => x + y

Resultatet av utvärderingen av ett funktionsuttryck är att skapa ett funktionsvärde (inte för att utvärdera funktionstexten). Som en konvention i det här dokumentet visas funktionsvärden (till skillnad från funktionsuttryck) med parameterlistan men med en ellips (...) i stället för funktionstexten. När funktionsuttrycket ovan till exempel har utvärderats visas det som följande funktionsvärde:

 (x, y) => ...

Följande operatorer definieras för funktionsvärden:

Operator Result
x = y Equal
x <> y Not equal

Den interna typen av funktionsvärden är en anpassad funktionstyp (härledd från den inbyggda typen function) som visar parameternamnen och anger alla parametertyper och returtypen som ska vara any. (Gå till Funktionstyper för information om funktionstyper.)

Anropa funktioner

Funktionens funktionstext körs genom att funktionsvärdet anropas med hjälp av ett invoke-expression. Att anropa ett funktionsvärde innebär att funktionstexten för funktionsvärdet utvärderas och ett värde returneras eller att ett fel utlöses.

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

Varje gång ett funktionsvärde anropas anges en uppsättning värden som en argumentlista som kallas argumenten för funktionen.

En argumentlista används för att ange ett fast antal argument direkt som en lista med uttryck. I följande exempel definieras en post med ett funktionsvärde i ett fält och sedan anropas funktionen från ett annat fält i posten:

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

Följande gäller när du anropar en funktion:

  • Miljön som används för att utvärdera funktionens funktionstext innehåller en variabel som motsvarar varje parameter, med samma namn som parametern. Värdet för varje parameter motsvarar ett värde som konstruerats från argumentlistan för invoke-expression enligt definitionen i Parametrar.

  • Alla uttryck som motsvarar funktionsargumenten utvärderas innan funktionstexten utvärderas.

  • Fel som uppstår vid utvärdering av uttrycken i uttryckslistan eller funktionstexten sprids.

  • Antalet argument som skapas från argumentlistan måste vara kompatibelt med funktionens parametrar, eller så uppstår ett fel med orsakskoden "Expression.Error". Processen för att fastställa kompatibilitet definieras i Parametrar.

Parametrar

Det finns två typer av parametrar som kan finnas i en parameterlista:

  • En obligatorisk parameter anger att ett argument som motsvarar parametern alltid måste anges när en funktion anropas. Obligatoriska parametrar måste anges först i parameterlistan. Funktionen i följande exempel definierar obligatoriska parametrar x och y:

      [ 
          MyFunction = (x, y) => x + y, 
    
          Result1 = MyFunction(1, 1),     // 2 
          Result2 = MyFunction(2, 2)      // 4
      ] 
    
  • En valfri parameter anger att ett argument som motsvarar parametern kan anges när en funktion anropas, men behöver inte anges. Om ett argument som motsvarar en valfri parameter inte anges när funktionen anropas används värdet null i stället. Valfria parametrar måste visas efter alla obligatoriska parametrar i en parameterlista. Funktionen i följande exempel definierar en fast parameter x och en valfri 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
      ] 
    

Antalet argument som anges när en funktion anropas måste vara kompatibelt med parameterlistan. Kompatibiliteten för en uppsättning argument A för en funktion F beräknas på följande sätt:

  • Låt värdet N representera antalet argument A som konstruerats från argumentlistan. Till exempel:

      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
    
  • Låt värdet Obligatoriskt representera antalet fasta parametrar F för och Valfritt antalet valfria parametrar för F. Till exempel:

    ()               // Required = 0, Optional = 0 
    (x)              // Required = 1, Optional = 0 
    (optional x)     // Required = 0, Optional = 1 
    (x, optional y)  // Required = 1, Optional = 1
    
  • Argument A är kompatibla med funktionen F om följande är sant:

    • (N >= Fast) och (N <= (Fast + valfritt))
    • Argumenttyperna är kompatibla med Fmotsvarande parametertyper
  • Om funktionen har en deklarerad returtyp är resultatvärdet för funktionens F brödtext kompatibelt med Freturtypen om följande är sant:

    • Värdet som returneras genom att utvärdera funktionstexten med de angivna argumenten för funktionsparametrarna har en typ som är kompatibel med returtypen.
  • Om funktionstexten ger ett värde som inte är kompatibelt med funktionens returtyp utlöses ett fel med orsakskoden "Expression.Error" .

Rekursiva funktioner

För att kunna skriva ett funktionsvärde som är rekursivt är det nödvändigt att använda omfångsoperatorn (@) för att referera till funktionen inom dess omfång. Följande post innehåller till exempel ett fält som definierar Factorial funktionen och ett annat fält som anropar den:

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

På samma sätt kan ömsesidigt rekursiva funktioner skrivas så länge varje funktion som behöver nås har ett namn. I följande exempel har en del av Factorial funktionen omstrukturerats till en andra Factorial2 funktion.

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

Nedläggningar

En funktion kan returnera en annan funktion som ett värde. Den här funktionen kan i sin tur vara beroende av en eller flera parametrar för den ursprungliga funktionen. I följande exempel returnerar funktionen som är associerad med fältet MyFunction en funktion som returnerar den angivna parametern:

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

Varje gång funktionen anropas returneras ett nytt funktionsvärde som underhåller värdet för parametern så att parametervärdet returneras när den anropas.

Funktioner och miljöer

Förutom parametrar kan funktionstexten för ett funktionsuttryck referera till variabler som finns i miljön när funktionen initieras. Funktionen som definieras av fältet MyFunction kommer till exempel åt fältet C för den omslutande posten A:

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

När MyFunction anropas får den åtkomst till värdet för variabeln C, även om den anropas från en miljö (B) som inte innehåller en variabel C.

Förenklade deklarationer

Varje uttryck är en syntaktisk förkortning för att deklarera otypade funktioner med en enda parameter med namnet _ (understreck).

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

Förenklade deklarationer används ofta för att förbättra läsbarheten för funktionsanrop med högre ordning.

Följande par med deklarationer är till exempel semantiskt likvärdiga:

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