Любая функция в языке Dart представляет тип Function и фактически может выступать в качестве отдельного объекта. Например, мы можем определить объект функции, присвоить ему динамически ссылку на какую-нибудь функцию и вызвать ее:
void main() { Function func = hello; func(); // Hello! func = bye; func(); // Goodbye! } void hello() => print("Hello!"); void bye() => print("Goodbye!");
В данном случае определяется переменная типа Function - func, и ей присваивается ссылка на функцию hello. Затем мы
выполнить переменную func как обычную функцию. Фактически в выражении func()
будет вызываться та функция,
на которую переменная func ссылается (то есть в первом случае функция hello). Кроме того, мы динамически можем изменить функцию, на которую ссылается переменная.
Консольный вывод:
Hello! Goodbye!
Функции могут выступать в качестве параметров других функций:
void main() { showMessage(hello); showMessage(bye); } void showMessage(Function func){ func(); // вызываем переданную функцию } void hello() => print("Hello!"); void bye() => print("Goodbye!");
Здесь в функцию showMessage в качестве параметра передаются функции hello и bye. В самой showMessage мы затем сможем вызвать переданные функции.
Другой пример:
void main() { operation(5, 4, sum); // 9 operation(5, 4, subtract); // 1 operation(5, 4, multiply); // 20 } void operation(int a, int b, Function func){ int result = func(a, b); // вызываем переданную функцию print(result); } int sum(int a, int b) => a+ b; int subtract(int a, int b) => a - b; int multiply(int a, int b) => a * b;
Здесь у нас есть три функции - sum, subtract и multiply, которые принимают два числа и выполняют над ними некоторую арифметическую операцию - сложение, вычитание и умножение.
Также есть функция operation, которая представляет некоторую операцию. Через первые два параметра она принимает числа для этой операции. А третий параметр представляет саму функцию:
void operation(int a, int b, Function func){ int result = func(a, b); // вызываем переданную функцию print(result); }
Причем здесь мы не знаем, какая именно функция будет передаваться через третий параметр. Мы только знаем, что это будет функция, которая принимает два числа и возращает некоторое число - результат операции.
И мы можем вызвать функцию operation, передав ей два числа и какую-нибудь функцию:
operation(5, 4, sum); // 9 operation(5, 4, subtract); // 1 operation(5, 4, multiply); // 20
Также функция может выступать в качестве возвращаемого значения:
void main() { Function message = getMessage(11); message(); message = getMessage(15); message(); } Function getMessage(int hour){ if(hour < 12) return morning; else return evening; } void morning() =>print("Good morning!"); void evening() =>print("Good evening!");
В данном случае функция getMessage в зависимости от от переданного числа возвращает либо функцию morning, либо функцию evening.
Затем в программе мы можем получить функцию и вызвать ее:
Function message = getMessage(11); message();
Чуть более сложный пример:
void main() { Function action = select(1); // получаем функцию add print(action(8, 5)); // 13 action = select(2); // получаем функцию subtract print(action(8, 5)); // 3 action = select(3); // получаем функцию multiply print(action(8, 5)); // 40 } Function select(int choice) { // возвращаем нужную функцию в зависимости от choice switch (choice) { case 2: return subtract; case 3: return multiply; default: return add; } } int add(int a, int b) => a+ b; int subtract(int a, int b) => a - b; int multiply(int a, int b) => a * b;
Здесь функция select в зависимости от значения параметра choice возвращает одну из функций - add, subtract или multiply, которые выполняют определенную операцию.
Далее мы можем вызвать эту функцию, передав ей определенное значение:
Function action = select(1); // получаем функцию add
Так, в данном случае будет возвращаться функция add. То есть переменная action фактически будет представлять функцию add. И затем мы можем вызвать эту функцию, передав ей пару чисел:
print(action(8, 5)); // 13