Przeczytaj w języku angielskim

Udostępnij za pośrednictwem


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ą).

Pisanie funkcji

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:

      optionalparametr
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 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 functionwewnę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).

Wywoływanie 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.

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 i y:

      [ 
          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 parametr x i opcjonalny 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
      ] 
    

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ówA. 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ów F. 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 Fparametrów
  • Jeśli funkcja ma zadeklarowany typ zwracany, wartość wyniku treści funkcji F jest zgodna z Ftypem 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.

Funkcje rekursywne

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 
]

Zamknięcia

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.

Funkcje i środowiska

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.

Uproszczone deklaracje

Każde wyrażenie jest skrótem składniowym do deklarowania nietypowych funkcji o nazwie _ (podkreślenie).

wyrażenie-każde:
      eachkaż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 )