Функция может выступать в качестве параметра другой функции. В этом случае типом параметра выступает тип функции. Рассмотрим следующий пример:
fn main(){ let sum: fn(i32, i32) -> i32 = |a, b| a + b; do_operation(6, 4, sum); do_operation(6, 4, multiply); } fn do_operation(a: i32, b: i32, operation: fn(i32, i32) -> i32){ let result = operation(a, b); println!("result: {}", result); } fn multiply(a: i32, b: i32) -> i32{ a * b }
Здесь функция do_operation()
в качестве третьего параметра принимает некоторую функцию, которая имеет тип fn(i32, i32) -> i32
.
То есть функцию, которая принимает два числа и возвращает некоторое число.
Для примера здесь определены две таких функции. Первая - полноценная функция multiply()
, которая возвращает результат умножения двух чисел.
Вторая функция - анонимная функция sum()
, которая возвращает результат сложения двух чисел.
При вызове функции do_operation()
мы можем передать в нее одну из этих двух функций - multiply и sum, поэтому что их тип соответствует типу третьего параметра функции
do_operation()
:
do_operation(6, 4, sum); do_operation(6, 4, multiply);
Консольный вывод:
result: 10 result: 24
Функция также может выступать в качестве возвращаемого значения другой функции. Например:
fn main(){ let operation1 = chose_operation(1); operation1(5, 4); let operation2 = chose_operation(2); operation2(5, 4); let operation3 = chose_operation(3); operation3(5, 4); } fn chose_operation(n:i32) -> fn(i32, i32){ match n{ 1 => |a, b|{println!("{}", a + b);}, 2 => multiply, _ => |a, b|{println!("a={} b={}", a, b);}, } } fn multiply(a: i32, b: i32){ println!("{}", a * b); }
Здесь функция chose_operation()
получает извне номер операции и возвращает функцию. В качестве типа возвращаемого результата
она имеет тип fn(i32, i32). А это значит, что возврашаемая функция должна принимать два значения типа i32
и ничего не возвращать.
Внутри функции chose_operation()
с помощью конструкции match в зависимости от переданного значения возвращаем ту или иную функцию.
Причем мы можем возвратить как анонимную функцию:
1 => |a, b|{println!("{}", a + b);},
Так и неанонимную функцию, которая соответствует типу fn(i32, i32):
2 => multiply,
В итоге результат вызова функции chose_operation()
будет представлять функцию, которую затем также можно вызвать, передав ей два числа:
let operation1 = chose_operation(1); operation1(5, 4);
Консольный вывод:
9 20 a=5 b=4