Анонимные функции в отличие от обычных функций не имеют имени и могут сохраняться в переменную.
Формальное определение анонимной функции:
let переменная = | параметры | { // выполняемые действия };
Анонимная функция определяется без оператора fn
. Ее определение фактически начинается с определения параметров,
которые помещаются между двумя вертикальными чертами: | параметры |
. Затем в фигурных скобках идут выполняемые
действия. Причем после закрывающей фигурной скобки ставится точка с запятой. При этом анонимная функция сохраняется в переменной.
Вызов анонимной функции похож на вызов обычной функции, только для вызова применяется имя переменной:
название_замыкания(значения_для_параметров);
Рассмотрим простейший пример:
fn main(){ let square = |n: i32|{ let result = n * n; println!("Квадрат числа {} равен {}", n, result); }; square(4); square(5); square(6); }
Здесь определена переменная square
, которая хранит анонимную функцию. Эта функция принимает один параметр типа i32
и
выводит на консоль его квадрат.
Консольный вывод программы:
Квадрат числа 4 равен 16 Квадрат числа 5 равен 25 Квадрат числа 6 равен 36
Анонимные функции также могут возвращать значение:
fn main(){ let sum = |a: i32, b: i32| -> i32{ a + b }; let sum_of_5_and_4 = sum(5, 4); println!("Сумма 5 и 4 равна: {}", sum_of_5_and_4); }
Здесь определена переменная sum
, которая представляет анонимную функцию, принимающую два параметра - два числа и возвращающую их сумму.
И по имени переменной мы можем вызвать эту анонимную функцию и получить ее результат.
Если анонимная функция не принимает никаких параметров, то просто указываются две вертикальных черты:
let hello =||{ // определение анонимной функции println!("hello"); }; hello(); // вызов анонимной функции
В отличие от обычной функции в анонимной можно не указывать типы параметров и возвращаемого результата. Для анонимной функции компилятор сам
способен определить типы параметров и результата. Например, мы могли бы переписать вышеопределенную анонимную функцию sum
следующим образом:
fn main(){ let sum = |a, b|{ // типы параметров и результата не указаны a + b }; let sum_of_5_and_4 = sum(5, 4); println!("Сумма 5 и 4 равна: {}", sum_of_5_and_4); }
Более того, так как анонимная функция содержит лишь одно выполняемое действие, то мы можем и фигурные скобки убрать:
fn main(){ let sum = |a, b| a + b; let sum_of_5_and_4 = sum(5, 4); println!("Сумма 5 и 4 равна: {}", sum_of_5_and_4); }
Однако стоит учитывать, что типы устанавливаются при первом вызове анонимной функции. И при последующих вызовах типы параметров и результатов анонимной функции должны соответствовать первому вызову. Например, в следующем случае мы получим ошибку при компиляции:
fn main(){ let sum = |a, b| a + b; let sum_of_int = sum(5, 4); let sum_of_float = sum(5.3, 4.2); println!("Сумма целых чисел: {}", sum_of_int); println!("Сумма дробных чисел: {}", sum_of_float); }
Потому что после первого вызова анонимной функции sum()
компилятор ожидает, что далее она будет принимать два целых числа. Однако во втором вызове
в данном случае передаются два числа с плавающей точкой.