Дротик | Flutter: как передать функцию из карты при нулевой безопасности? Зачем нужен оператор взрыва?

Фон:

Я изучал, как передавать функции с помощью карты с помощью кода дротика. Однако сейчас я в тупике. Я получаю неожиданное нулевое значение из следующего кода при использовании DartPad при использовании нулевой безопасности:

      void main() {
Map<String, Function> fruits = Map();
  fruits['apple'] = appleDescription;
  fruits['banana'] = bananaDescription;
  fruits['grape'] = grapeDescription;
  
  exec(fruits['grape']!);
}

void appleDescription() => print('This fruit tastes like red!');
void bananaDescription() => print('This fruit tastes like yellow!');
void grapeDescription() => print('This fruit tastes like purple!');

void exec(Function f) {
    print(f());
}

Консоль DartPad показана на рисунке ниже:

Вопросов:

Я думаю, что ответ будет легким, но я уже некоторое время серьезно борюсь с этим. Мои вопросы:

  1. Я только этого ожидал: «Этот фрукт на вкус как фиолетовый!» был напечатан в консоли, поэтому мне что-то здесь не хватает. Правильно ли я передаю эту функцию с карты или есть более безопасный способ передачи?

  2. Я задавался вопросом, почему я должен использовать оператор взрыва при вызове функции exec(). Поскольку я определил, что карта фруктов содержит <String, Function>, компилятор поймет, что она должна существовать. Что мне не хватает?

Опять же, заранее спасибо за любой совет, с благодарностью принимаемый от сообщества.

Обновлять:

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

      void main() {
Map<String, Function> fruits = Map();
  fruits['apple'] = appleDescription;
  fruits['banana'] = bananaDescription;
  fruits['cranberry'] = grapeDescription;
  
  exec(fruits['cranberry']??= (){print('');});
}

void appleDescription() => print('This fruit tastes like red!');
void bananaDescription() => print('This fruit tastes like yellow!');
void grapeDescription() => print('This fruit tastes like purple!');

void exec(Function f) {
    f();
}

1 ответ

Решение

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

Итак, в основном:

  1. код входит
  2. звонки
  3. f() печатает This fruit tastes like purple! и возвращается void
  4. метод в exec напечатать возвращаемое значение => null

Подводя итог, вы печатаете возвращаемое значение print функция.

Чтобы ваш код работал так, как вы ожидаете, вы должны использовать

      void exec(Function f) {
    f();
}

Чтобы ответить на ваш второй вопрос, возвращается банка nullвы не передаете ему действующий ключ. Вот почему вы должны использовать челку, потому что возвращение Map не может быть гарантированно ненулевым.

Другие вопросы по тегам