betacode

Замыкания (Closure) в Dart

  1. Что такое Closure?
  2. Синтаксис стрелки
  3. Класс функций
  4. Closure в параметре

1. Что такое Closure?

В языке программирования Dart,Closure (закрытая крышка) - это специальная функция.
  • Подобно функции, Closure представляет собой блок операторов с параметрами и может возвращать значение или ничего.
  • В отличие от функции, Closure не имеет имени. Однако вы можете определить Closure с помощью переменной.
Синтаксис:
// Closure syntax
(data_type1 arg1, data_type2 arg2, data_typeN argN) {
   // Statements
}
// Declare a variable as an alias for Closure
var alias = (data_type1 arg1, data_type2 arg2, data_typeN argN) {
   // Statements
};
Например: Мы объявляем Closure с 1 параметром и вызываем его напрямую.
closure_ex1.dart
void main() {  
  // Create a Closure!
  (String name) {
    print('Hello $name!');
  };
  // Create a Closure and call it directly!
  (String name)  {
    print('Bye $name!');
  }('Tom');
}
Output:
Bye Tom!
Например: Объявите переменную в качестве идентификатора для Closure:
closure_ex2.dart
void main() {  
  // Declare a variable as an alias for Closure
  var sum = (int a, int b) {
    return a + b;
  };
  // Call a closure.
  var result = sum(100, 200); // 300
  print('result = $result');
}

2. Синтаксис стрелки

Если содержимое of Closure состоит только из одного выражения, вы можете написать его более лаконично с помощью синтаксиса стрелки (Arrow syntax):
var alias1 =  (data_type1 arg1, data_type2 arg2, data_typeN argN) {
     print('Something');
}
// Same as:
var alias1 =  (data_type1 arg1, data_type2 arg2, data_typeN argN) => print('Something');

var alias2 =  (data_type1 arg1, data_type2 arg2, data_typeN argN) {
     return a_value;
}
// Same as:
var alias2 =  (data_type1 arg1, data_type2 arg2, data_typeN argN)  => a_value;
Например:
closure_arrow_ex1.dart
void main() {
  // Create a Closure
  var sum = (int a, int b) => a + b;

  var result = sum(100, 200); // Call a closure.
  print('result = $result');

  // Create a Closure
  var sayHello = (String name) => print('Hello $name');
  sayHello('Tom'); // Call a closure.
}
Output:
result = 300
Hello Tom

3. Класс функций

В языке Dart, Closure является объектом класса Function, поэтому вы можете объявить Closure со следующим синтаксисом:
Синтаксис:
Function(type1 arg1, type2 arg2, typeN argN) func = (type1 arg1, type2 arg2, typeN argN) {
   // Statements
};
// Or:
return_type Function(type1 arg1, type2 arg2, typeN argN) func;

func = (type1 arg1, type2 arg2, typeN argN) {
   // Statements
};
Например:
closure_func_ex1.dart
void main() {
  // Function Type: (int, int) --> (int)
  Function(int a, int b) sum = (int a, int b) {
    return a + b;
  };
  // Function Type: (int, int) --> (int)
  int Function(int a, int b) minus;
  minus = (int a, int b) => a - b;

  var result1 = sum(100, 200); // 300
  print('result1 = $result1');

  var result2 = minus(100, 200); // -100
  print('result2 = $result2');
}

4. Closure в параметре

Closure может отображаться как параметр другой функции, closure, метода или constructor.
// A Function to calculate Tax.
// It accepts 2 arguments:
//  1 - int amount
//  2 - Closure
void printTaxAmount(int amount, double Function(int amount) taxFormula) {
  var tax = taxFormula(amount);
  print('tax = $tax');
}

// Same as:
void printTaxAmount(int amount, double taxFormula(int amount)) {
  var tax = taxFormula(amount);
  print('tax = $tax');
}
Например:
closure_in_args_ex1.dart
// A Function to calculate Tax.
// It accepts 2 arguments:
//  1 - int amount
//  2 - Closure
void printTaxAmount(int amount, double Function(int amount) taxFormula) {
  var tax = taxFormula(amount);
  print('tax = $tax');
}
void main() {
  // Create a Closure (Tax calucation formula of US)
  var usTaxFormula = (int amount) {
    return 10 * amount / 100; // return a double type.
  };
  // Create a Closure (Tax calucation formula of Vietnam)
  var vnTaxFormula = (int amount) {
    return 5 * amount / 100; // return a double type.
  };
  const amount = 1000;
  printTaxAmount(amount, usTaxFormula); // 100.0
  printTaxAmount(amount, vnTaxFormula); // 50.0
}
Output:
tax = 100.0
tax = 50.0
List.generate Example:
Constructor List.generate класса List имеет Closure в качестве параметра. Давайте посмотрим пример того, как использовать этот constructor.
List.generate Constructor
external factory List.generate(int length, E generator(int index), {bool growable = true});
Например:
closure_in_args_ex3.dart
// List.generate Constructor:
// external factory List.generate(int length, E generator(int index), {bool growable = true});
void main() {
  // (int index) --> (String)
  var generator = (int index) {
    return 'Value ' + index.toString();
  };
  // Create a List with 5 elements:
  List<String> myList = List.generate(5, generator, growable: true);
  print(myList); // [Value 0, Value 1, Value 2, Value 3, Value 4]
}
Output:
[Value 0, Value 1, Value 2, Value 3, Value 4]