Функция может выступать в качестве параметра другой функции. В этом случае типом параметра выступает тип функции. Рассмотрим следующий пример:
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