Číst v angličtině

Sdílet prostřednictvím


Funkce

Funkce je hodnota, která představuje mapování ze sady hodnot argumentů na jednu hodnotu. Funkce je vyvolána poskytnutím sady vstupních hodnot (hodnot argumentů) a vytvoří jednu výstupní hodnotu (návratovou hodnotu).

Psaní funkcí

Funkce se zapisují pomocí výrazu function:

function-expression:
      ( parametr-listopt)function-return-typeopt=>function-body
function-body:
      výraz
parameter-list:
      fixed-parameter-list
      fixed-parameter-list
, optional-parameter-list
      optional-parameter-list
fixed-parameter-list:
      parametr
      parameter
, fixed-parameter-list
parametr:
      opt parametr-name parametr-type
název parametru:
      identifikátor
parametr-type:
      assertion
function-return-type:
      assertion
tvrzení:

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

      optionalparametr
nullable-primitve-type
      nullable
opt primitive-type

Následuje příklad funkce, která vyžaduje přesně dvě hodnoty x a ya vytvoří výsledek použití operátoru + na tyto hodnoty. y Jedná se o x parametry, které jsou součástí seznamu parametrů funkce a jedná se x + y o tělo funkce:

(x, y) => x + y

Výsledkem vyhodnocení výrazu function-expression je vytvoření hodnoty funkce (nikoli vyhodnocení těla funkce). Jako konvence v tomto dokumentu se hodnoty funkcí (na rozdíl od výrazů funkcí) zobrazují se seznamem parametrů, ale se třemi tečkami (...) místo těla funkce. Například po vyhodnocení výše uvedeného výrazu funkce by se zobrazila jako následující hodnota funkce:

 (x, y) => ...

Pro hodnoty funkcí jsou definovány následující operátory:

Operátor Výsledek
x = y Equal
x <> y Not equal

Nativní typ hodnot funkce je vlastní typ funkce (odvozený z vnitřního typu function), který uvádí názvy parametrů a určuje všechny typy parametrů a návratový typ, který má být any. (Přejít na Typy funkcí pro podrobnosti o typech funkcí.)

Vyvolání funkcí

Tělo funkce se provádí vyvoláním hodnoty funkce pomocí výrazu invoke-expression. Vyvolání hodnoty funkce znamená, že se vyhodnotí tělo funkce hodnoty funkce a vrátí se hodnota nebo se vyvolá chyba.

invoke-expression:
      primární výraz
(argument-list opt )
argument-list:
      seznam výrazů

Při každém vyvolání hodnoty funkce se sada hodnot zadává jako seznam argumentů označovaný jako argumenty funkce.

Seznam argumentů slouží k určení pevného počtu argumentů přímo jako seznam výrazů. Následující příklad definuje záznam s hodnotou funkce v poli a potom vyvolá funkci z jiného pole záznamu:

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

Při vyvolání funkce platí následující:

  • Prostředí použité k vyhodnocení těla funkce obsahuje proměnnou, která odpovídá jednotlivým parametrům se stejným názvem jako parametr. Hodnota každého parametru odpovídá hodnotě vytvořené ze seznamu argumentů invoke-expression, jak je definováno v parametrech.

  • Všechny výrazy odpovídající argumentům funkce se vyhodnocují před vyhodnocením těla funkce.

  • Chyby vyvolané při vyhodnocování výrazů v seznamu výrazů nebo textu funkce se šíří.

  • Počet argumentů vytvořených ze seznamu argumentů musí být kompatibilní s parametry funkce nebo je vyvolána chyba s kódem "Expression.Error"důvodu . Proces určení kompatibility je definován v parametrech.

Parametry

V seznamu parametrů existují dva druhy parametrů:

  • Povinný parametr označuje, že při vyvolání funkce musí být vždy zadán argument odpovídající parametru. Požadované parametry musí být zadány jako první v seznamu parametrů. Funkce v následujícím příkladu definuje požadované parametry x a y:

      [ 
          MyFunction = (x, y) => x + y, 
    
          Result1 = MyFunction(1, 1),     // 2 
          Result2 = MyFunction(2, 2)      // 4
      ] 
    
  • Volitelný parametr označuje, že při vyvolání funkce může být zadán argument odpovídající parametru, ale není nutné ho zadat. Pokud argument odpovídající volitelnému parametru není zadán při vyvolání funkce, použije se místo toho hodnota null . Volitelné parametry se musí zobrazit za všemi požadovanými parametry v seznamu parametrů. Funkce v následujícím příkladu definuje pevný parametr x a volitelný parametr 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
      ] 
    

Počet argumentů zadaných při vyvolání funkce musí být kompatibilní se seznamem parametrů. Kompatibilita sady argumentů A pro funkci F se vypočítá takto:

  • Nechte hodnotu N reprezentovat počet argumentů A vytvořených ze seznamu argumentů. Příklad:

      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
    
  • Nechte hodnotu Povinný představuje počet pevných parametrů F a Nepovinný počet volitelných parametrů .F Příklad:

    ()               // Required = 0, Optional = 0 
    (x)              // Required = 1, Optional = 0 
    (optional x)     // Required = 0, Optional = 1 
    (x, optional y)  // Required = 1, Optional = 1
    
  • Argumenty A jsou kompatibilní s funkcí F , pokud jsou splněny následující podmínky:

    • (N >= pevné) a (N <= (pevné + volitelné))
    • Typy argumentů jsou kompatibilní s odpovídajícími Ftypy parametrů.
  • Pokud má funkce deklarovaný návratový typ, je výsledná hodnota těla funkce F kompatibilní s návratovým typem F, pokud je splněna následující hodnota:

    • Hodnota vrácená vyhodnocením těla funkce se zadanými argumenty pro parametry funkce má typ, který je kompatibilní s návratovým typem.
  • Pokud tělo funkce vrátí hodnotu nekompatibilní s návratovým typem funkce, vyvolá se chyba s kódem "Expression.Error" důvodu.

Rekurzivní funkce

Aby bylo možné napsat hodnotu funkce, která je rekurzivní, je nutné použít operátor oboru (@) k odkazování na funkci v rámci oboru. Například následující záznam obsahuje pole, které definuje Factorial funkci, a další pole, které ji vyvolá:

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

Podobně lze vzájemně rekurzivní funkce zapsat, pokud každá funkce, ke které je potřeba přistupovat, má název. V následujícím příkladu Factorial byla část funkce refaktorována na druhou Factorial2 funkci.

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

Uzavírky

Funkce může vrátit jinou funkci jako hodnotu. Tato funkce může záviset na jednom nebo více parametrech na původní funkci. V následujícím příkladu vrátí funkce přidružená k poli MyFunction funkci, která vrátí zadaný parametr:

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

Při každém vyvolání funkce se vrátí nová hodnota funkce, která zachová hodnotu parametru tak, aby při jejím vyvolání byla vrácena hodnota parametru.

Funkce a prostředí

Kromě parametrů může tělo funkce výrazu funkce odkazovat na proměnné, které jsou přítomné v prostředí při inicializaci funkce. Například funkce definovaná polem MyFunction přistupuje k poli C ohraničujícího záznamu A:

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

Při MyFunction vyvolání přistupuje k hodnotě proměnné C, i když je vyvolána z prostředí (B), který neobsahuje proměnnou C.

Zjednodušené deklarace

Každý výraz je syntaktická zkratka pro deklarování netypových funkcí s jedním parametrem s názvem _ (podtržítko).

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

Zjednodušené deklarace se běžně používají ke zlepšení čitelnosti vyvolání funkce vyššího pořadí.

Například následující dvojice deklarací jsou sémanticky ekvivalentní:

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