flutter - 主体可能正常完成,导致返回“null”,但返回类型可能是不可为空的类型
问题描述
我正在使用新的 dart 版本 >=2.12.0 <3.0.0 并启用了 null 安全性。
我添加了我的代码以供参考。
火柴服务
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,
),
],
),
),
),
);
}
}
我收到此错误:正文可能正常完成,导致返回“null”,但返回类型可能是不可为空的类型。尝试在末尾添加 return 或 throw 语句。
解决方案
在 Dart 中,如果您的函数没有return
语句,则其行为与返回相同null
。例如:
dynamic doesntReturn() {
// do nothing
}
print(doesntReturn()); // prints 'null'
在您的情况下,getMatches()
是一个返回 async 的函数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
}
但是,您的函数不能 return null
,因为它的返回类型为Future<List<MatchModel>>
. 异步有点复杂,但以下同步代码具有相同的行为:
List<MatchModel> getMatches() {
try {
return _doSomeCalculation();
} catch (e) {
print(e);
}
}
要解决此问题,您需要确保return null
永远不会命中隐式。您可以:
- 重新抛出错误,因此
getMatches()
抛出:
Future<List<MatchModel>> getMatches() async {
try {
var matchList = await fetchMatches();
list.add(matchList);
return matchList;
} catch (Exc) {
print(Exc);
rethrow;
}
- 返回一些其他值,也许是一个空列表?
- 更改
getMatches
为返回Future<List<MatchModel>?>
- 永远循环(或其他静态类型的表达式
Never
)
我可能会推荐选项 1),但这取决于您的用例
推荐阅读
- scala - avro4s 无法反序列化 AnyRef
- sql - 如何每天在 Azure 数据库上运行 T-SQL 查询
- selenium - 如何在 PowerBi Dashboards 上自动化数据验证测试?
- c# - 在 RibbonSplitButton 中突出显示上面的所有元素
- c# - 更改按钮单击时的标签文本也执行其他方法
- wildfly - 用于 Microsoft azureload 平衡器的 Wildfly jboss 独立配置
- python - 在 Python 中打印以日期格式“yyyy-mm-dd”开头的日志文件的行
- c# - 具有分组、空值和许多连接的 Linq 查询
- c++ - QMediaPlayer 在 dll 中不起作用
- r - 循环以无法正常工作的方式填充 NA