身体可能正常完成,导致返回“null”,但返回类型是潜在的不可为空类型。

12

我正在使用新的Dart版本 >=2.12.0 <3.0.0,并启用了空安全特性。

我添加了我的代码供参考。

MatchesService

import 'package:cric_app/AppUrls.dart';
import 'package:cric_app/features/home/match_model.dart';
import 'package:dio/dio.dart';
import 'package:rxdart/rxdart.dart';

class MatchesService {
  // ignore: close_sinks
  BehaviorSubject<List<MatchModel>> list = BehaviorSubject<List<MatchModel>>();

  Future<List<MatchModel>> getMatches() async {
    try {
      var matchList = await fetchMatches();
      list.add(matchList);
      return matchList;
    } catch (Exc) {
      print(Exc);
    }
  }

  Future<List<MatchModel>> fetchMatches() async {
    var dio = Dio();
    final response = await dio.post(AppUrls.getMatches);
    print(response.data);
    final body = response.data['matches'] as List;
    return body.map((dynamic json) {
      return MatchModel(
        id: json['id'] as int,
        date: json['date'] as String,
        dateGmt: json['dateTimeGMT'] as String,
        teamOne: json['team-1'] as String,
        teamTwo: json['team-2'] as String,
        tossWinnerTeam: json['toss_winner_team'] as String,
        matchStarted: json['matchStarted'] as bool,
        type: json['type'] as String,
        winnerTeam: json['winner_team'] as String,
      );
    }).toList();
  }
}

主屏幕

import 'package:cric_app/components/match_card.dart';
import 'package:cric_app/features/home/match_model.dart';
import 'package:cric_app/features/home/matches_service.dart';
import 'package:cric_app/utils.dart';
import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  MatchesService matchesService = MatchesService();

  @override
  void initState() {
    matchesService.getMatches();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: primary_color,
      body: SingleChildScrollView(
        child: Container(
          margin: setMargin(15, 0, 15, 0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              SizedBox(
                height: 30,
              ),
              text('Matches', Colors.white, FontWeight.bold, 23),
              SizedBox(
                height: 2,
              ),
              text("Today's live matches", Colors.white, FontWeight.bold, 18),
              StreamBuilder<List<MatchModel>>(
                stream: matchesService.list,
                initialData: null,
                builder: (context, snapshot) {
                  if (snapshot.data != null) {
                    final list = snapshot.data as List;
                    return ListView.builder(
                      itemCount: list.length,
                      itemBuilder: (BuildContext context, int index) {
                        return matchCard(context, list[index]);
                      },
                    );
                  } else {
                    return Center(
                      child: text(
                        'No live matches now',
                        Colors.white,
                        FontWeight.bold,
                        16,
                      ),
                    );
                  }
                },
              ),
              SizedBox(
                height: 10,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

我遇到了这个错误: The body might complete normally, causing 'null' to be returned, but the return type is a potentially non-nullable type. Try adding either a return or a throw statement at the end.

4个回答

34
在Dart中,如果您的函数没有return语句,那么它的行为就像返回null一样。例如:
dynamic doesntReturn() {
  // do nothing
}
print(doesntReturn());  // prints 'null'

在您的情况下,getMatches() 是一个异步函数,返回一个 Future<List<MatchModel>>。然而,在您的 catch 块中,您没有返回任何东西,导致隐式的 return null

  Future<List<MatchModel>> getMatches() async {
    try {
      var matchList = await fetchMatches();
      list.add(matchList);
      return matchList;
    } catch (Exc) {
      print(Exc);
    }

  // "return null" added implicitly
  }

但是,由于函数的返回类型是Future<List<MatchModel>>,它不能返回null。虽然异步性使情况有点复杂,但以下同步代码具有相同的行为:

List<MatchModel> getMatches() {
  try {
    return _doSomeCalculation();
  } catch (e) {
    print(e);
  }
}
为了解决这个问题,您需要确保隐式的 return null 永远不会被触发。您可以选择重新抛出错误,这样 getMatches() 就会抛出错误:
  1. 重新抛出错误,这样 getMatches() 就会抛出错误。
  Future<List<MatchModel>> getMatches() async {
    try {
      var matchList = await fetchMatches();
      list.add(matchList);
      return matchList;
    } catch (Exc) {
      print(Exc);
      rethrow;
    }
  1. 返回其他值,也许是一个空列表?
  2. getMatches更改为返回Future<List<MatchModel>?>
  3. 无限循环(或其他具有静态类型Never的表达式)

我可能会建议选择选项1),但这取决于您的用例。


0
只需在小部件中添加一个返回语句。 例如: Divider();
返回 Divider();

-3

我也遇到了这个问题,并通过以下步骤解决:

  1. 进入 pubspec.yaml 文件
  2. 查找以下内容 - environment: sdk: ">=2.12.0 <3.0.0"
  3. 修改为 - environment: sdk: ">=2.11.0 <3.0.0"

-8

方法体可能正常完成,导致返回 'null',但返回类型是一个潜在的非空类型。 尝试在结尾添加一个 return 或 throw 语句。


1
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接