为什么Dart的编译器认为代码可能为空,而代码却保证它不能为空?

9w11ddsr  于 2023-02-20  发布在  其他
关注(0)|答案(1)|浏览(123)

我正在做this course中的一个练习。

void main() {
  const order = ['pepperoni', 'margherita', 'pineapple'];
  print("Total: ${calculateTotal(order)}");

}

double calculateTotal(List<String> order) {
  var total = 0.0;
  const pizzaPrices = {
    'margherita': 5.5,
    'pepperoni': 7.5,
    'vegetarian': 6.5,
  };
  for (var item in order) {
    if (pizzaPrices[item]!=null) {
    total += pizzaPrices[item];
    } 
  }
  
  return total;
}

生成指向行total += pizzaPrices[item];的错误消息The argument type 'double?' can't be assigned to the parameter type 'num'.
total += pizzaPrices[item]!按预期编译,没有错误。
我不明白为什么编译器需要!,因为它已经知道pizzaPrices[item]不能为空。

ffx8fchx

ffx8fchx1#

原因是Map上的[]运算符被定义为返回一个可空类型,因为如果您搜索的元素不在map中,[]运算符将返回null
这对您来说可能看起来很明显,但是编译器不能确定仅仅因为您检查了pizzaPrices[item]的返回值一次,它就会在您第二次请求时再次返回相同的值(例如,在一些定制的Map实现中)。
一个解决方案是将值保存在一个局部变量中,然后您可以检查null。在这种情况下,Dart将按预期提升变量:

void main() {
  const order = ['pepperoni', 'margherita', 'pineapple'];
  print("Total: ${calculateTotal(order)}");
}

double calculateTotal(List<String> order) {
  var total = 0.0;
  const pizzaPrices = {
    'margherita': 5.5,
    'pepperoni': 7.5,
    'vegetarian': 6.5,
  };
  for (var item in order) {
    final pizzaPrice = pizzaPrices[item];

    if (pizzaPrice != null) {
      total += pizzaPrice;
    }
  }

  return total;
}

相关问题