Поделиться через


Функции

Функция — это значение, представляющее сопоставление из набора значений аргументов с одним значением. Функция вызывается предоставленным набором входных значений (значения аргументов) и создает одно выходное значение (возвращаемое значение).

Написание функций

Функции записываются с помощью выражения функции:

function-expression:
       ( Выбор списка) параметроввариант возврата=> типаfunction-body
тело-функции:
      выражение
parameter-list:
      список-фиксированных-параметров
      fixed-parameter-list
,необязательный-параметр-list
      список-необязательных-параметров
список-фиксированных-параметров:
      параметр
      параметр
,fixed-parameter-list
parameter:
      имя-параметра тип-параметранеобязательно
имя-параметра:
      идентификатор
тип-параметра:
      примитив-или-nullable-primitive-type-assert
return-type:
      примитив-или-nullable-primitive-type-assert
примитив-или-nullable-primitive-type-assert:

       as примитив-или-nullable-primitive-type
список-необязательных-параметров:
      необязательный-параметр
      необязательный параметр
,необязательный-параметр-list
необязательный-параметр:

       optional параметр
примитив-или-nullable-primitive-type:
       nullable opt primitive-type

Ниже приведен пример функции, которая требует ровно двух значений x и yсоздает результат применения + оператора к этим значениям. И x являются y, которые являются частью списка параметров функции, и является x + y функции:

(x, y) => x + y

Результатом вычисления выражения функции является создание значения функции (не для вычисления тела функции). В качестве соглашения в этом документе значения функций (в отличие от выражений функций) отображаются с списком параметров, но с многоточием (...) вместо тела функции. Например, после вычисления приведенного выше выражения функции он будет отображаться как следующее значение функции:

 (x, y) => ...

Для значений функций определены следующие операторы:

Оператор Результат
x = y Equal
x <> y Не равно

Собственный тип значений функции — это пользовательский тип функции (производный от встроенного типа function), который перечисляет имена параметров и задает все типы параметров и возвращаемый тип any. (Перейти к Типы функций для подробных сведений о типах функций.)

Вызов функций

Текст функции выполняется путем вызова значения функции с помощью выражения invoke-expression. Вызов значения функции означает, что вычисляется тело функции и возвращается значение или возникает ошибка.

выражение-вызова:
      Выбор аргумента первичного выражения
()
список-аргументов:
      список-выражений

Каждый раз при вызове значения функции набор значений указывается как список аргументов, называемый аргументами функции.

Список аргументов используется для указания фиксированного числа аргументов непосредственно в виде списка выражений. В следующем примере определяется запись со значением функции в поле, а затем вызывает функцию из другого поля записи:

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

При вызове функции выполняется следующее:

  • Среда, используемая для вычисления тела функции, включает переменную, соответствующую каждому параметру, с тем же именем, что и параметр. Значение каждого параметра соответствует значению, созданному из списка аргументов вызова-выражения, как определено в параметрах.

  • Все выражения, соответствующие аргументам функции, вычисляются перед вычислением тела функции.

  • Ошибки, возникающие при оценке выражений в списке выражений или текстефункции, распространяются.

  • Число аргументов, созданных из списка аргументов, должно быть совместимо с параметрами функции или возникает ошибка с кодом "Expression.Error"причины. Процесс определения совместимости определен в параметрах.

Параметры

Существует два типа параметров, которые могут присутствовать в списке параметров:

  • Обязательный параметр указывает, что аргумент, соответствующий параметру, всегда должен быть указан при вызове функции. Обязательные параметры должны быть указаны сначала в списке параметров. Функция в следующем примере определяет обязательные параметры x и y:

      [ 
          MyFunction = (x, y) => x + y, 
    
          Result1 = MyFunction(1, 1),     // 2 
          Result2 = MyFunction(2, 2)      // 4
      ] 
    
  • Необязательный параметр указывает, что аргумент, соответствующий параметру, может быть указан при вызове функции, но не требуется указывать. Если аргумент, соответствующий необязательному параметру, не указан при вызове функции, вместо этого используется значение null . Необязательные параметры должны отображаться после всех обязательных параметров в списке параметров. Функция в следующем примере определяет фиксированный параметр x и необязательный параметр 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
      ] 
    

Число аргументов, указанных при вызове функции, должно быть совместимо со списком параметров. Совместимость набора аргументов A для функции F вычисляется следующим образом:

  • Пусть значение N представляет число аргументов, созданных из A аргументов. Например:

      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
    
  • Пусть значение "Обязательный" представляет число фиксированных параметров F и необязательное число необязательных параметров F. Например:

    ()               // Required = 0, Optional = 0 
    (x)              // Required = 1, Optional = 0 
    (optional x)     // Required = 0, Optional = 1 
    (x, optional y)  // Required = 1, Optional = 1
    
  • Аргументы A совместимы с функцией F , если указаны следующие значения:

    • (N >= фиксированные) и (N <= (фиксированные + необязательные))
    • Типы аргументов совместимы с Fсоответствующими типами параметров
  • Если функция имеет объявленный тип возвращаемого значения, результат текста функции F совместим с Fтипом возвращаемого значения, если задано значение true:

    • Значение, возвращаемое путем вычисления текста функции с заданными аргументами для параметров функции, имеет тип, совместимый с возвращаемым типом.
  • Если тело функции выдает значение, несовместимое с типом возвращаемого значения, возникает ошибка с кодом "Expression.Error" причины.

Рекурсивные функции

Чтобы написать значение функции, рекурсивное, необходимо использовать оператор области (@) для ссылки на функцию в пределах области. Например, следующая запись содержит поле, определяющее Factorial функцию, и другое поле, которое вызывает его:

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

Аналогичным образом рекурсивные функции могут быть записаны до тех пор, пока у каждой функции, к которым требуется получить доступ, есть имя. В следующем примере часть Factorial функции была рефакторингова вторую Factorial2 функцию.

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

Замыкания

Функция может возвращать другую функцию в качестве значения. Эта функция, в свою очередь, может зависеть от одного или нескольких параметров исходной функции. В следующем примере функция, связанная с полем MyFunction , возвращает функцию, возвращающую указанный ему параметр:

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

При каждом вызове функции будет возвращено новое значение функции, которое сохраняет значение параметра, чтобы при его вызове возвращалось значение параметра.

Функции и среды

Помимо параметров, текстфункции выражения функции может ссылаться на переменные, присутствующих в среде при инициализации функции. Например, функция, определяемая полем, обращается к полю MyFunctionC заключающей записи A:

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

При MyFunction вызове он обращается к значению переменной C, даже если он вызывается из среды (B), которая не содержит переменную C.

Упрощенные объявления

Каждое выражение — это синтаксическое сокращение для объявления нетипизированных функций, принимающие один параметр с именем _ (подчеркивание).

каждое выражение:
       each каждый текст выражения
тело-выражения-each:
      тело-функции

Упрощенные объявления обычно используются для улучшения удобочитаемости вызова функции более высокого порядка.

Например, следующие пары объявлений семантически эквивалентны:

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