我对以下代码段发出警告,但我不知道为什么。
List<Map<String, int>> callNoInfo = [];
int getCallNo(String phoneNo) {
callNoInfo.forEach((item) {
if (item.containsKey(phoneNo)) {
return item[phoneNo];
}
});
return 0;
}
警告是:
This function has a return type of 'int', but doesn't end with a return statement. (missing_return at [project_name] lib\helper\call_no.dart:35)
谁能告诉我为什么会这样?预先感谢
答案 0 :(得分:3)
在forEach
方法中,您正在创建lambda函数而未显式定义返回类型,因此Dart试图从return
语句中推断出它。如果我们从forEach
方法中提取函数,那么可能有助于了解我的意思:
...
(item) {
if (item.containsKey(phoneNo)) {
return item[phoneNo];
}
}
...
该函数包含一个return
语句,该语句返回item[phoneNo]
,它是一个int
值。 Dart使用此推断出此lambda函数的返回类型为int
。但是,现在知道了这一点,它还注意到,如果代码执行未进入if
块,则没有return
语句与{{1 }}条件。如果else
对象不包含键if
,该方法将返回什么?
(答案是该方法将隐式返回item
,这就是为什么该消息只是警告而不是编译器错误的原因,但出现警告是因为您可能不是故意这样做的。开发人员,也可以帮助您使代码减少对隐形Dart运行时魔术的依赖。)
要解决此问题,在phoneNo
块之外还需要另一个null
:
return
但是,现在有另一个问题。列表上的if
方法具有以下签名:
...
(item) {
if (item.containsKey(phoneNo)) {
return item[phoneNo];
}
return 0;
}
...
实际上,有两个问题。首先,作为参数传递的方法需要具有返回类型forEach
,而forEach(void f(E element)) → void
方法本身也具有返回类型void
。这意味着您根本无法从forEach
方法中返回值。
关于void
方法的事情是,它旨在遍历集合并处理其中的每个值。这并不是要(也不能)搜索值并在找到后返回它。此外,迭代是详尽无遗的,这意味着一旦启动迭代,就无法停止该方法,直到对集合中的每个元素都进行了迭代为止。
正如其他答案所指出的,这就是为什么您真正应该使用forEach
或forEach
循环的原因:
for
(我不确定为什么将for in
的返回值分配给List<Map<String, int>> callNoInfo = [];
int getCallNo(String phoneNo) {
for(var item in callNoInfo) {
if (item.containsKey(phoneNo)) {
return item[phoneNo];
}
}
return 0;
}
的lambda函数不会出现编译器错误,该方法显然正在请求一个带有int
返回类型。但是,如果我不得不猜测,我会说Dart运行时将它们视为兼容并通过简单地丢弃lambda函数的返回值来调和返回类型的差异。)
答案 1 :(得分:-2)
forEach
循环内的if语句没有其他情况。即使最后可能会有一个,但仍然希望到处都是这样。
List<Map<String, int>> callNoInfo = [];
int getCallNo(String phoneNo) {
callNoInfo.forEach((item) {
if (item.containsKey(phoneNo)) {
return item[phoneNo];
}
// you don't have a case for here since it's in a callback
});
return 0;
}
但是,您可以使用for in
循环来做到这一点:
List<Map<String, int>> callNoInfo = [];
int getCallNo(String phoneNo) {
for (var item in callNoInfo) {
if (item.containsKey(phoneNo)) {
return item[phoneNo];
}
}
return 0;
}