Оценок пока нет Функции в языке Dart

Dart — это настоящий объектно-ориентированный язык, поэтому даже функции являются объектами и имеют тип Function.

Это означает, что функции могут быть назначены переменным или переданы в качестве аргументов другим функциям. Вы также можете вызвать экземпляр класса Dart, как если бы это была функция. Для получения дополнительной информации см. Callable классы.

Вот пример реализации функции:

bool isNoble(int atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

Хотя Effective Dart рекомендует аннотации типов для общедоступных API-интерфейсов, функция все равно работает, если вы опустите типы:

isNoble(atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

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

bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;

Синтаксис => expr является сокращением для {return expr; }. Обозначение => иногда называют синтаксисом стрелки.

елкой (=>) и точкой с запятой (;) может появляться только выражение, но не утверждение. Например, вы не можете поместить туда оператор if, но вы можете использовать условное выражение.

Функция может иметь два типа параметров: обязательные и необязательные. Обязательные параметры перечислены первыми, а затем все необязательные параметры. Необязательные параметры могут быть именованными или позиционными.

Примечание. Некоторые API, в частности конструкторы виджетов Flutter, используют только именованные параметры, даже для обязательных параметров. Смотрите следующий раздел для деталей.
Дополнительные параметры

Необязательные параметры могут быть именованными или позиционными, но не обоими.

Именованные параметры

При вызове функции вы можете указать именованные параметры, используя paramName: value. Например:

enableFlags(bold: true, hidden: false);

При определении функции используйте {param1, param2,…} для указания именованных параметров:

/// Sets the [bold] and [hidden] flags ...
void enableFlags({bool bold, bool hidden}) {...}

Хотя именованные параметры являются своего рода необязательным параметром, их можно аннотировать с помощью @required, чтобы указать, что параметр является обязательным, — что пользователи должны предоставить значение для параметра. Например:

const Scrollbar({Key key, @required Widget child})

Если кто-то пытается создать Scrollbar без указания дочернего аргумента child, то анализатор сообщает о проблеме.

Чтобы использовать аннотацию @required, зависит от пакета meta и импорта: package:meta/meta.dart.

Позиционные параметры

Обертывание набора параметров функции в [] помечает их как необязательные позиционные параметры:

String say(String from, String msg, [String device]) {
  var result = '$from says $msg';
  if (device != null) {
    result = '$result with a $device';
  }
  return result;
}

Вот пример вызова этой функции без необязательного параметра:

assert(say('Bob', 'Howdy') == 'Bob says Howdy');

И вот пример вызова этой функции с третьим параметром:

assert(say('Bob', 'Howdy', 'smoke signal') ==
    'Bob says Howdy with a smoke signal');
Значения параметров по умолчанию

Ваша функция может использовать = для определения значений по умолчанию для именованных и позиционных параметров. Значения по умолчанию должны быть константами времени компиляции. Если значение по умолчанию не указано, значением по умолчанию является null.

Вот пример установки значений по умолчанию для именованных параметров:

/// Sets the [bold] and [hidden] flags ...
void enableFlags({bool bold = false, bool hidden = false}) {...}

// bold will be true; hidden will be false.
enableFlags(bold: true);
Примечание об устаревании: Старый код может использовать двоеточие (:) вместо = для установки значений по умолчанию именованных параметров. Причина в том, что изначально, только : был поддержан для именованных параметров. Эта поддержка может быть устаревшей, поэтому мы рекомендуем использовать знак =, чтобы указать значения по умолчанию.

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

String say(String from, String msg,
    [String device = 'carrier pigeon', String mood]) {
  var result = '$from says $msg';
  if (device != null) {
    result = '$result with a $device';
  }
  if (mood != null) {
    result = '$result (in a $mood mood)';
  }
  return result;
}

assert(say('Bob', 'Howdy') ==
    'Bob says Howdy with a carrier pigeon');

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

void doStuff(
    {List<int> list = const [1, 2, 3],
    Map<string, string=""> gifts = const {
      'first': 'paper',
      'second': 'cotton',
      'third': 'leather'
    }}) {
  print('list:  $list');
  print('gifts: $gifts');
}
The main() function

Каждое приложение должно иметь функцию main() верхнего уровня, которая служит точкой входа в приложение. Функция main() возвращает void и имеет необязательный параметр List <String> для аргументов.

Вот пример функции main() для веб-приложения:

void main() {
  querySelector('#sample_text_id')
    ..text = 'Click me!'
    ..onClick.listen(reverseText);
}
Примечание. Синтаксис .. в предыдущем коде называется каскадом cascade . С помощью каскадов вы можете выполнять несколько операций над элементами одного объекта.

Вот пример функции main() для приложения командной строки, которое принимает аргументы:

// Run the app like this: dart args.dart 1 test
void main(List<string> arguments) {
  print(arguments);

  assert(arguments.length == 2);
  assert(int.parse(arguments[0]) == 1);
  assert(arguments[1] == 'test');
}

Вы можете использовать библиотеку args для определения и анализа аргументов командной строки.

Функции как первоклассные объекты

Вы можете передать функцию в качестве параметра другой функции. Например:

void printElement(int element) {
  print(element);
}

var list = [1, 2, 3];

// Pass printElement as a parameter.
list.forEach(printElement);

Вы также можете назначить функцию переменной, например:

var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
assert(loudify('hello') == '!!! HELLO !!!');

В этом примере используется анонимная функция. Подробнее об этом в следующем разделе.

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

Большинство функций имеют имена, такие как main() или printElement(). Вы также можете создать анонимную функцию, называемую анонимной функцией, иногда лямбда-выражением или замыканием. Вы можете назначить анонимную функцию переменной, чтобы, например, вы могли добавить или удалить ее из коллекции.

Анонимная функция выглядит аналогично именованной функции — ноль или более параметров, разделенных запятыми и необязательными аннотациями типов, заключаются в круглые скобки.

Следующий блок кода содержит тело функции:

([[Type] param1[, …]]) {
  codeBlock;
};

В следующем примере определяется анонимная функция с нетипизированным параметром item. Функция, вызываемая для каждого элемента в списке, печатает строку, содержащую значение по указанному индексу.

var list = ['apples', 'bananas', 'oranges'];
list.forEach((item) {
  print('${list.indexOf(item)}: $item');
});
void main() {
  var list = ['apples', 'bananas', 'oranges'];
  list.forEach((item) {
    print('${list.indexOf(item)}: $item');
  });
}

Если функция содержит только один оператор, вы можете сократить его, используя обозначение стрелки. Вставьте следующую строку в DartPad и нажмите «Выполнить», чтобы убедиться, что она функционально эквивалентна.

list.forEach((item) => print('${list.indexOf(item)}: $item'));
Лексическая область

Dart — это язык с лексической областью, что означает, что область видимости переменных определяется статически, просто компоновкой кода. Вы можете «следовать за фигурными скобками наружу», чтобы увидеть, находится ли переменная в области видимости.

Вот пример вложенных функций с переменными на каждом уровне области действия:

bool topLevel = true;

void main() {
  var insideMain = true;

  void myFunction() {
    var insideFunction = true;

    void nestedFunction() {
      var insideNestedFunction = true;

      assert(topLevel);
      assert(insideMain);
      assert(insideFunction);
      assert(insideNestedFunction);
    }
  }
}

Обратите внимание, как nestedFunction() может использовать переменные с каждого уровня, вплоть до верхнего уровня.

Лексические крышки

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

Функции могут закрывать переменные, определенные в окружающих областях. В следующем примере makeAdder() захватывает переменную addBy. Куда бы ни возвращалась возвращаемая функция, она запоминает addBy.

/// Returns a function that adds [addBy] to the
/// function's argument.
Function makeAdder(num addBy) {
  return (num i) => addBy + i;
}

void main() {
  // Create a function that adds 2.
  var add2 = makeAdder(2);

  // Create a function that adds 4.
  var add4 = makeAdder(4);

  assert(add2(3) == 5);
  assert(add4(3) == 7);
}
Проверка функций на равенство

Вот пример тестирования функций верхнего уровня, статических методов и методов экземпляра на равенство:

void foo() {} // A top-level function

class A {
  static void bar() {} // A static method
  void baz() {} // An instance method
}

void main() {
  var x;

  // Comparing top-level functions.
  x = foo;
  assert(foo == x);

  // Comparing static methods.
  x = A.bar;
  assert(A.bar == x);

  // Comparing instance methods.
  var v = A(); // Instance #1 of A
  var w = A(); // Instance #2 of A
  var y = w;
  x = w.baz;

  // These closures refer to the same instance (#2),
  // so they're equal.
  assert(y.baz == x);

  // These closures refer to different instances,
  // so they're unequal.
  assert(v.baz != w.baz);
}
Возвращаемые значения

Все функции возвращают значение. Если возвращаемое значение не указано, инструкция return null; неявно добавляется к телу функции.

foo() {}
assert(foo() == null);

Пожалуйста, оцените материал

WebSofter

Web - технологии