Эта функция имеет тип возврата «int», но не заканчивается оператором return

#flutter #dart

Вопрос:

Предупреждение:

 This function has a return type of 'int', but doesn't end with a return statement.  Try adding a return statement, or changing the return type to 'void'.
 

Я получаю предупреждение в этом коде:

 int _duration = 0;
  int getDuration(String date) {
    //print("Date $date");
    //load the data from firebase and add to the list
    fb.reference()
      ..child(cuser.uid)
          .child('Seizure_history')
          .child(date)
          .once()
          .then((DataSnapshot snapshot) {
        var data = snapshot.value;
        list = List();
        if (data != null) {
          data.forEach((key, value) {
            EventList seizure_history = new EventList(
              seiz_duration: value['duration'],
              dateTime: value['datetime'],
              key: key,
            );
            list.add(seizure_history);
            setState(() {
              _duration = int.parse(list[list.length - 1].seiz_duration);
            });
            print("Duration $_duration");
            return _duration;
          });
        }
      });
  }
 

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

Я хочу вернуть длительность после ее нахождения в firebase, но она все еще показывает ноль, что означает, что значение не возвращается, почему это происходит. Я новичок в флаттере и все еще учусь.

обновленный:

эта функция вызывается внутри initState() :

 var series;
  var data;
  //Charts
  getCharts()
  {
    data = [
      addcharts(sevenDay.substring(0, 2), getDuration(seven),
          charts.ColorUtil.fromDartColor(const Color(0xffe8e5af))),
      addcharts(sixDay.substring(0, 2), getDuration(six),
          charts.ColorUtil.fromDartColor(const Color(0xffe8e5af))),
      addcharts(fiveDay.substring(0, 2),getDuration(five),
          charts.ColorUtil.fromDartColor(const Color(0xffe8e5af))),
      addcharts(fourDay.substring(0, 2), getDuration(four),
          charts.ColorUtil.fromDartColor(const Color(0xffe8e5af))),
      addcharts(threeDay.substring(0, 2), getDuration(three),
          charts.ColorUtil.fromDartColor(const Color(0xffe8e5af))),
      addcharts(twoDay.substring(0, 2), getDuration(two),
          charts.ColorUtil.fromDartColor(const Color(0xffe8e5af))),
      addcharts(oneDay.substring(0, 2), getDuration(one),
          charts.ColorUtil.fromDartColor(const Color(0xffe8e5af))),
    ];
    series = [
      charts.Series(
        domainFn: (addcharts addcharts, _) => addcharts.weeks,
        measureFn: (addcharts addcharts, _) => addcharts.duration,
        colorFn: (addcharts addcharts, _) => addcharts.barColor,
        id: 'addcharts',
        data: data,
      ),
    ];

  }
 

Как я могу использовать внутри него будущего строителя? Вот где я застрял, если я использую FutureBuilder

 Expanded(
                                child: charts.BarChart(
                                  series,
                                  animationDuration: Duration(microseconds: 2000),
                                ),
                              )
 

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

1. Вы возвращаете Duration экземпляр внутри if блока, который, в свою очередь, находится внутри моментального снимка ( then() ), а затем внутри forEach цикла, лучше создать переменную с некоторой продолжительностью по умолчанию, обновить ее в блоке if и вернуть ту же переменную или, возможно, использовать обратный вызов.

2. @DarShan Не просто беритесь за имена переменных.

Ответ №1:

Во-первых, вы должны выполнить асинхронное вычисление внутри асинхронного метода:

 // Return a Future<int> and add async to its declaration
Future<int> getDuration(String date) async {
  final DataSnapshot snapshot = await (fb.reference()
    ..child(cuser.uid)
    .child('Seizure_history')
    .child(date)
    .once());

  var data = snapshot.value;

  // Return a default value in case `snapshot.value` is null
  if (data == null) return 0;

  list = [];
  data.forEach((key, value) {
    final EventList seizure_history = new EventList(
      seiz_duration: value['duration'],
      dateTime: value['datetime'],
      key: key,
    );
    list.add(seizure_history);
    setState(() {
        _duration = int.parse(list[list.length - 1].seiz_duration);
    });
    return _duration;
  });
}
 

Однако ваша логика не имеет смысла. Вы пытаетесь вернуть значение ( _duration ) внутри для каждого, поэтому есть две возможности: 1) вы хотите вернуть первую длительность из data ; или 2) вы хотите вернуть все длительности из data . Вот как вы можете поступить в обеих ситуациях:

  1. Возврат первой продолжительности из data
 Future<int> getDuration(String date) async {
  // ...

  list = [];

  // Get the first entry from data
  var entry = data.first;

  final EventList seizure_history = EventList(
    seiz_duration: entry.value['duration'],
    dateTime: entry.value['datetime'],
    key: entry.key,
  );
  list.add(seizure_history);

  // Get the seizure duration
  final int duration = int.parse(seizure_history.seiz_duration);
  setState(() => _duration = duration);
  return duration;
}
 
  1. Возврат всех длительностей из data
 // Since there are multiple durations, use a List<int> instead of int
final List<int> _durations = [];

// Update the method signature
Future<List<int>> getDuration(String date) async {
  // ...

  // Create a local `_durations` to update the property's one only once  
  final List<int> durations = [];

  // Use a map to fetch all the durations
  list = data.map((key, value) {
    final EventList seizure_history = new EventList(
      seiz_duration: value['duration'],
      dateTime: value['datetime'],
      key: key,
    );

    // Add the duration to the local's one
    durations.add(int.parse(seizure_history.seiz_duration);

    // Add the seizure history to the list
    return seizure_history;
  }).toList();

  setState(() => _durations = durations);
  return durations;
}
 

Конечно , вам нужно изменить, куда вы звоните getDuration , так как теперь он возвращает a Future , но вы можете использовать FutureBuilder виджет, чтобы помочь вам в этом.

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

1. Привет! спасибо вам за решение. Но не могли бы вы помочь мне понять, как я могу реализовать будущий конструктор с помощью flutter_charts, поскольку я создаю гистограмму и вызываю функцию getDuration() внутри, где используются диаграммы

2. Я понимаю вашу точку зрения на использование FutureBuilder, но не могли бы вы предоставить решение, как я могу реализовать его с помощью диаграмм, я обновил свой пост

Ответ №2:

Вам просто нужно вернуть int в конце вашей функции, вот так:

 int getDuration(String date) {
    //print("Date $date");
    //load the data from firebase and add to the list
    fb.reference()
      ..child(cuser.uid)
          .child('Seizure_history')
          .child(date)
          .once()
          .then((DataSnapshot snapshot) {
        var data = snapshot.value;
        list = List();
        if (data != null) {
          data.forEach((key, value) {
            EventList seizure_history = new EventList(
              seiz_duration: value['duration'],
              dateTime: value['datetime'],
              key: key,
            );
            list.add(seizure_history);
            setState(() {
              _duration = int.parse(list[list.length - 1].seiz_duration);
            });
            print("Duration $_duration");
            return _duration;
          });
        }
      });
    return 0;
  }
 

Ошибка возникает из-за того, что, когда вы определяли свою функцию, вы сказали, что она вернет int тип, но если условия не будут выполнены, она ничего не вернет (и, следовательно, не возвращает int ).

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

1. Ваши ответы неверны, потому что использование вашего кода getDuration всегда будет возвращать 0, а это не то, что хотел ОП («Я хочу вернуть длительность после ее нахождения в firebase, но она все еще показывает ноль»).

Ответ №3:

Вам также необходимо вернуться int в случае, если вы Future потерпите неудачу.

 int getDuration(String date) {
  fb.reference(...);
  
  return 0; // Return something here. 
}
 

или

Измените тип возврата на int? :

 int? getDuration(String date) {...}
 

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

1. Я не могу использовать ненулевой язык