Функции
Функция — это значение, представляющее сопоставление из набора значений аргументов с одним значением. Функция вызывается предоставленным набором входных значений (значения аргументов) и создает одно выходное значение (возвращаемое значение).
Функции записываются с помощью выражения функции:
function-expression:
(
параметр-listopt function-return-typeopt)
=>
function-body
тело-функции:
выражение
parameter-list:
список-фиксированных-параметров
fixed-parameter-list ,
необязательный-параметр-list
список-необязательных-параметров
список-фиксированных-параметров:
параметр
параметр ,
fixed-parameter-list
parameter:
имя-параметра тип-параметранеобязательно
имя-параметра:
идентификатор
тип-параметра:
assertion
тип-возвращаемого-значения-функции:
assertion
assertion:
as
nullable-primiitve-type
список-необязательных-параметров:
необязательный-параметр
необязательный параметр ,
необязательный-параметр-list
необязательный-параметр:
optional
параметр
тип-примитива-допускающий-значение-NULL
nullable
opt primitive-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
]
При каждом вызове функции будет возвращено новое значение функции, которое сохраняет значение параметра, чтобы при его вызове возвращалось значение параметра.
Помимо параметров, текст функции выражения функции может ссылаться на переменные, присутствующих в среде при инициализации функции. Например, функция, определяемая полем, обращается к полю MyFunction
C
заключающей записи 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 )