dart говорит, что «ненулевая переменная должна быть инициализирована перед использованием», даже после назначения с помощью блока if, else

#flutter #dart #scope

Вопрос:

Пытаюсь это сделать. Было бы здорово, если бы я мог избежать реализации полного кода в обоих условиях.

   String dateToday;
  //if time is past 6pm, get next date:
  if (fetchTime.hour > 18){
    final dateToday = DateFormat('dd-MM-yyyy').format(fetchTime.add(Duration(days: 1)));
  }
  else{
    final dateToday = DateFormat('dd-MM-yyyy').format(fetchTime);
  }

  final Map<String, String> params = {
      'district_id': '$districtId',
      'date': dateToday                //ERROR HERE  <------
  }
 

ошибка:

Локальная переменная, не допускающая значения null, «dateToday» должна быть назначена, прежде чем ее можно будет использовать. Попробуйте задать ему выражение инициализатора или убедитесь, что оно назначено на каждом пути выполнения.

Ответ №1:

Я считаю, что вы используете неправильно. Вы должны установить значение в уже определенную переменную. Другими словами, в этом случае не используйте ключевое слово final.

   String dateToday;   //if time is past 6pm, get next date:   
  if (fetchTime.hour > 18){
    dateToday = DateFormat('dd-MM-yyyy').format(fetchTime.add(Duration(days: 1)));   
  } else{
    dateToday = DateFormat('dd-MM-yyyy').format(fetchTime);   
  }

  final Map<String, String> params = {
      'district_id': '$districtId',
      'date': dateToday    }
 

Обновление из комментария автора, добавленного OP:

при объявлении переменной следует использовать ключевое слово final. Поскольку дата сегодня уже была объявлена, использование final внутри области создает новую локальную переменную dateToday, а внешняя дата сегодня остается неназначенной.

Комментарии:

1. Ты прав. Удаление финала сделало это. Насколько я понимаю, final следует использовать, когда значение переменной фиксируется в этот момент.

2. Можете ли вы объяснить немного подробнее, почему final не следует использовать здесь? Поскольку значение впоследствии не изменится, почему бы не использовать его. Флаттеру нравится иметь финал везде, где это возможно.

3. Согласно документам Dart, ключевое слово final используется для жесткого кодирования значений переменной, и оно не может быть изменено в будущем, ни какие-либо операции, выполняемые с этими переменными, не могут изменить ее значение (состояние). Кроме того, если вы хотите задать значение в какой-либо переменной, вы должны сначала объявить эту переменную. Вы уже объявили свою переменную перед условием if. Это означает, что вы не должны использовать ключевое слово final в данном случае @VaisakMohan

Ответ №2:

когда вы используете final там, вы объявляете новую переменную как в области if, так и в области else, тип которой автоматически является динамическим. поэтому ваша начальная переменная dateToday не будет назначена. когда вы пытаетесь прочитать его извне оператора if и else, вы ссылаетесь на свою строковую переменную dateToday, которая не назначена. Поэтому dart жалуется, что вы не назначили переменную перед использованием.

Попробуйте использовать это

  late String dateToday;
      //if time is past 6pm, get next date:
      if (fetchTime.hour > 18){
        dateToday = DateFormat('dd-MM-yyyy').format(fetchTime.add(Duration(days: 1)));
      }
      else{
        dateToday = DateFormat('dd-MM-yyyy').format(fetchTime);
      }
    
      final Map<String, String> params = {
          'district_id': '$districtId',
          'date': dateToday                //ERROR HERE  <------
      }
 

Комментарии:

1. Это сработало. Даже без ключевого слова «поздно».

2. Можете ли вы объяснить немного подробнее, почему final не следует использовать здесь? Поскольку значение впоследствии не изменится, почему бы не использовать его.

3. когда вы используете final там, вы объявляете новую переменную как в области if, так и в области else, тип которой автоматически является динамическим. поэтому ваша начальная переменная dateToday не будет назначена. когда вы пытаетесь прочитать его извне оператора if и else, вы ссылаетесь на свою строковую переменную dateToday, которая не назначена. Поэтому dart жалуется, что вы не назначили переменную перед использованием.