Funkcje
Funkcja to wartość reprezentująca mapowanie z zestawu wartości argumentów na pojedynczą wartość. Funkcja jest wywoływana przez podany zestaw wartości wejściowych (wartości argumentów) i tworzy pojedynczą wartość wyjściową (wartość zwracaną).
Funkcje są pisane przy użyciu wyrażenia-funkcji:
wyrażenie-funkcji:
(
parametr-listopt)
function-return-typeopt=>
function-body
function-body:
wyrażenie
parametr-lista:
stała lista parametrów
fixed-parameter-list optional-parameter-list,
opcjonalna lista parametrów
fixed-parameter-list:
parametr
parametr ,
fixed-parameter-list
parametr:
parametr-nazwa-typ-parametruopt
nazwa-parametru:
identifier
typ parametru:
assertion
funkcja-return-type:
assertion
twierdzenie:
as
nullable-primiitve-type
opcjonalna lista parametrów:
opcjonalny parametr
optional-parameter ,
optional-parameter-list
opcjonalny parametr:
optional
parametr
nullable-primitve-type
nullable
opt typ pierwotny
Poniżej przedstawiono przykład funkcji, która wymaga dokładnie dwóch wartości x
i y
, i daje wynik zastosowania +
operatora do tych wartości. Parametry x
i y
są częścią listy parametrów funkcji, a element x + y
jest funkcją body:
(x, y) => x + y
Wynikiem oceny wyrażenia-funkcji jest wygenerowanie wartości funkcji (nie do oceny treści funkcji). Jako konwencja w tym dokumencie wartości funkcji (w przeciwieństwie do wyrażeń funkcji) są wyświetlane z listą parametrów, ale z wielokropkiem (...
) zamiast treści funkcji. Na przykład po obliczeniu powyższego wyrażenia funkcji będzie ono wyświetlane jako następująca wartość funkcji:
(x, y) => ...
Następujące operatory są definiowane dla wartości funkcji:
Operator | Result |
---|---|
x = y |
Equal |
x <> y |
Not equal |
Natywnym typem wartości funkcji jest typ funkcji niestandardowej (pochodzący z typu function
wewnętrznego ), który zawiera listę nazw parametrów i określa wszystkie typy parametrów i zwracany typ ma być any
. (Przejdź do Typy funkcji, aby uzyskać szczegółowe informacje na temat typów funkcji).
Treść funkcji jest wykonywana przez wywołanie wartości funkcji przy użyciu wyrażenia invoke-. Wywołanie wartości funkcji oznacza, że treść funkcji wartości funkcji jest obliczana i zwracana jest wartość lub zgłaszany jest błąd.
wyrażenie-wywołania:
opcja listy argumentów(
wyrażenia podstawowego )
lista argumentów:
lista wyrażeń
Za każdym razem, gdy wywoływana jest wartość funkcji, zestaw wartości jest określany jako lista-argumentów, nazywanych argumentami funkcji.
Lista argumentów służy do określania stałej liczby argumentów bezpośrednio jako listy wyrażeń. Poniższy przykład definiuje rekord z wartością funkcji w polu, a następnie wywołuje funkcję z innego pola rekordu:
[
MyFunction = (x, y, z) => x + y + z,
Result1 = MyFunction(1, 2, 3) // 6
]
Podczas wywoływania funkcji są przechowywane następujące elementy:
Środowisko używane do oceny treści funkcji funkcji zawiera zmienną odpowiadającą każdemu parametrowi o tej samej nazwie co parametr. Wartość każdego parametru odpowiada wartości skonstruowanej z listy argumentów wyrażenia-wywołania, zgodnie z definicją w parametrach.
Wszystkie wyrażenia odpowiadające argumentom funkcji są oceniane przed obliczeniu treści funkcji.
Błędy zgłaszane podczas oceniania wyrażeń na liście wyrażeń lub treści funkcji są propagowane.
Liczba argumentów utworzonych z listy argumentów musi być zgodna z parametrami funkcji lub zgłaszany jest błąd z kodem
"Expression.Error"
przyczyny . Proces określania zgodności jest definiowany w obszarze Parametry.
Istnieją dwa rodzaje parametrów, które mogą być obecne na liście parametrów:
Wymagany parametr wskazuje, że argument odpowiadający parametrowi musi być zawsze określony po wywołaniu funkcji. Wymagane parametry muszą być określone jako pierwsze na liście parametrów. Funkcja w poniższym przykładzie definiuje wymagane parametry
x
iy
:[ MyFunction = (x, y) => x + y, Result1 = MyFunction(1, 1), // 2 Result2 = MyFunction(2, 2) // 4 ]
Opcjonalny parametr wskazuje, że argument odpowiadający parametrowi może zostać określony podczas wywoływanej funkcji, ale nie jest wymagany do określenia. Jeśli argument odpowiadający opcjonalnemu parametrowi nie zostanie określony podczas wywoływanej funkcji, zamiast tego zostanie użyta wartość
null
. Parametry opcjonalne muszą pojawić się po wszelkich wymaganych parametrach na liście parametrów. Funkcja w poniższym przykładzie definiuje stały parametrx
i opcjonalny parametry
:[ 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 ]
Liczba argumentów określonych podczas wywoływanej funkcji musi być zgodna z listą parametrów. Zgodność zestawu argumentów A
funkcji F
jest obliczana w następujący sposób:
Niech wartość N reprezentuje liczbę argumentów skonstruowanych z listy argumentów
A
. Na przykład: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
Niech wartość Wymagana reprezentuje liczbę stałych parametrów
F
i Opcjonalnie liczbę opcjonalnych parametrówF
. Na przykład:() // Required = 0, Optional = 0 (x) // Required = 1, Optional = 0 (optional x) // Required = 0, Optional = 1 (x, optional y) // Required = 1, Optional = 1
Argumenty
A
są zgodne z funkcjąF
, jeśli są spełnione następujące warunki:- (N >= Naprawiono) i (N <= (Naprawiono + Opcjonalnie))
- Typy argumentów są zgodne z odpowiednimi typami
F
parametrów
Jeśli funkcja ma zadeklarowany typ zwracany, wartość wyniku treści funkcji
F
jest zgodna zF
typem zwracanym przez funkcję, jeśli jest to prawda:- Wartość zwrócona przez ocenę treści funkcji z podanymi argumentami parametrów funkcji ma typ zgodny z typem zwracanym.
Jeśli treść funkcji zwraca wartość niezgodną z typem zwracanym funkcji, zostanie zgłoszony błąd z kodem
"Expression.Error"
przyczyny.
Aby napisać wartość funkcji rekursywną, należy użyć operatora określania zakresu (@
), aby odwołać się do funkcji w jej zakresie. Na przykład następujący rekord zawiera pole, które definiuje Factorial
funkcję, i inne pole, które go wywołuje:
[
Factorial = (x) =>
if x = 0 then 1 else x * @Factorial(x - 1),
Result = Factorial(3) // 6
]
Podobnie wzajemnie rekursywne funkcje mogą być zapisywane tak długo, jak każda funkcja, do których należy uzyskać dostęp, ma nazwę. W poniższym przykładzie część Factorial
funkcji została refaktoryzowana do drugiej Factorial2
funkcji.
[
Factorial = (x) => if x = 0 then 1 else Factorial2(x),
Factorial2 = (x) => x * Factorial(x - 1),
Result = Factorial(3) // 6
]
Funkcja może zwrócić inną funkcję jako wartość. Ta funkcja może z kolei zależeć od jednego lub większej liczby parametrów do oryginalnej funkcji. W poniższym przykładzie funkcja skojarzona z polem MyFunction
zwraca funkcję, która zwraca określony parametr:
[
MyFunction = (x) => () => x,
MyFunction1 = MyFunction(1),
MyFunction2 = MyFunction(2),
Result = MyFunction1() + MyFunction2() // 3
]
Za każdym razem, gdy funkcja zostanie wywołana, zostanie zwrócona nowa wartość funkcji, która zachowuje wartość parametru, tak aby po wywołaniu zwracana będzie wartość parametru.
Oprócz parametrów treść funkcji wyrażenia funkcji może odwoływać się do zmiennych, które znajdują się w środowisku podczas inicjowania funkcji. Na przykład funkcja zdefiniowana przez pole MyFunction
uzyskuje dostęp do pola C
otaczającego rekordu A
:
[
A =
[
MyFunction = () => C,
C = 1
],
B = A[MyFunction]() // 1
]
Po MyFunction
wywołaniu uzyskuje ona dostęp do wartości zmiennej C
, mimo że jest wywoływana ze środowiska (B
), które nie zawiera zmiennej C
.
Każde wyrażenie jest skrótem składniowym do deklarowania nietypowych funkcji o nazwie _
(podkreślenie).
wyrażenie-każde:
each
każda treść wyrażenia
każda treść wyrażenia:
treść funkcji
Uproszczone deklaracje są często używane do poprawy czytelności wywołania funkcji o wyższej kolejności.
Na przykład następujące pary deklaracji są semantycznie równoważne:
each _ + 1
(_) => _ + 1
each [A]
(_) => _[A]
Table.SelectRows( aTable, each [Weight] > 12 )
Table.SelectRows( aTable, (_) => _[Weight] > 12 )