Функции

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

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

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

function-expression:
      (список-параметровнеобязательно)тип-возвращаемого-значения-функциинеобязательно=>тело-функции
тело-функции:
      выражение
parameter-list:
      список-фиксированных-параметров
      список-фиксированных-параметров
,список-необязательных-параметров
      список-необязательных-параметров
список-фиксированных-параметров:
      параметр
      параметр
,список-фиксированных-параметров
parameter:
      имя-параметра тип-параметранеобязательно
имя-параметра:
      идентификатор
тип-параметра:
      assertion
тип-возвращаемого-значения-функции:
      assertion
assertion:

      asпримитивный-тип-допускающий-значение-NULL
список-необязательных-параметров:
      необязательный-параметр
      необязательный-параметр
,список-необязательных-параметров
необязательный-параметр:

      optionalпараметр
тип-примитива-допускающий-значение-NULL
      nullable
optprimitive-type

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

(x, y) => x + y

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

 (x, y) => ...

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

Оператор Результат
x = y Equal
x <> y Not equal

Собственный тип значений функции — это пользовательский тип функции (производный от встроенного типа 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:
      тело-функции

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

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

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