Анонимные и вложенные функции

Последнее обновление: 02.04.2023

Анонимные функции

Анонимные функции похожи на обычные функции за тем исключением, что они не имеют названия. Например:

void main() {
	
	Function sum = (a, b) => a + b;
	print(sum(4, 5));		// 9
	print(sum(6, 5));		// 11
}

В данном случае переменной sum присваивается ссылка на анонимную функцию (a, b) => a + b, которая принимает два параметра и возвращает сумму их значений.

В данном случае анонимная функция имеет сокращенную запись, но мы также ее можем развернуть:

void main() {
	
	Function sum = (int a, int b)
	{
		print("Sum of $a and $b");
		return a + b;
	};
	print(sum(4, 5));
}

Где имеет смысл использовать анонимные функции? Если мы вызываем функцию, которая принимает другую функцию, то для функции-параметра может быть проще использовать анонимную функцию, чем определять именованную, особенно если именованная функция нам больше нигде не понадобится:

void main() {
	
    operation(10, 4, (a, b)=>a + b);    // 14
    operation(10, 4, (a,b)=>a - b);     // 6
    operation(10, 4, (a, b) => a * b);  // 40
}

void operation(int a, int b, Function op)
{
    print(op(a, b)); 
}

В данном случае функция operation в качестве третьего параметра принимает некоторую функцию, которая выполняет некоторые действия над двумя числами и возвращает результат. И вместо того, чтобы определять специально функции, которые больше нигде не будут использоваться, здесь напрямую передаем в функцию operation анонимные функции.

Также можно возвращать из функции анонимные функции:

void main() {
     
    Function action = select(1);  // сложение
    print(action(8, 5)); // 13

    action = select(2);  // вычитание
    print(action(8, 5)); // 3

    action = select(3);  // умножение
    print(action(8, 5)); // 40
}
Function select(int choice)
{
    // возвращаем нужную функцию в зависимости от choice
    switch (choice)
    {
        case 2:
            return (a, b) => a - b;
        case 3:
            return (a, b) => a * b;
        default:
            return (a, b) => a + b;
    }
}

Вложенные функции

В Dart функции могут быть вложенными в другие функции:

void main() {
	
	void hello(){
		print("Hello!");
	}
	
	hello();
	hello();
}

Причем определение вложенной функции должно идти до ее вызова. Вложенные функции имеют смысл, если мы планируем использовать некие повторяющиеся действия только внутри определенной функции.

Причем вложенные функции сами могут содержать другие вложенные функции:

void main() {
	
	void showMessage(){
		void hello(){
			print("Hello!");
		}
		
		hello();
		hello();
	}
	
	showMessage();
}

Стоит отметить, что вложенные функции образуют собственный контекст - переменные и константы, к которым внешняя функция не может обратиться. Например:

void main() {
     
    void welcome(){
		var message = "Welcome!";
        print(message);
    }
     
	print(message);	// ! Ошибка - внешняя функция не может обращаться к переменным вложенных функций.
}

В данном случае переменная message определена внутри функции welcome, поэтому может вызываться только в рамках этой функции, но не вне ее.

Дополнительные материалы
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850