【问题标题】:The parameter can't have a value of 'null' because of its type in Dart该参数的值不能为“null”,因为它在 Dart 中的类型
【发布时间】:2020-07-27 21:46:12
【问题描述】:

飞镖功能

我有以下 Dart 函数,我现在使用 null 安全:

void calculate({int factor}) {
  // ...
}

分析器抱怨:

参数'factor'因其类型不能有'null'的值,并且没有提供非空的默认值。

颤振小部件

我在 Flutter 中的 StatelessWidget 也是这样:

class Foo extends StatelessWidget {
  const Foo({Key key}): super(key: key);

  // ...
}

我收到以下错误:

参数'key'因其类型不能有'null'的值,并且没有提供非空的默认值。


我该如何解决这个问题?

【问题讨论】:

    标签: flutter dart dart-null-safety


    【解决方案1】:

    为什么

    发生这种情况的原因是因为启用了 null 安全,您的 non-nullable 参数 factorkey 不能 是 @ 987654323@.

    在函数和构造函数中,当函数在没有命名参数的情况下调用时,这些值可能nullcalculate()Foo()。但是,由于类型(intKey)是不可为空的,这是无效代码 - 它们决不能为空。

    解决方案

    基本上有三种方法可以解决这个问题:

    required

    这可能是该问题最常见的解决方案,它表示必须设置变量。这意味着如果我们有(注意 required 关键字):

    void calculate({required int factor}) {
      // ...
    }
    

    我们指出必须始终指定factor 参数,这解决了问题,因为只有calculate(factor: 42) 等。将是函数的有效调用。

    默认值

    另一种解决方案是提供默认值。如果我们的参数有默认值,我们可以放心地在调用函数时不指定参数,因为将使用默认值:

    void calculate({int factor = 42}) {
      // ...
    }
    

    现在,calculate() 调用将使用42 作为factor,这显然是非空的。

    可以为空的参数

    第三种解决方案是您真正要考虑的问题,即您是否想要一个可为空的参数?如果是这样,则在函数中使用该参数时必须对参数进行空值检查。

    但是,这是您最常希望解决 Key key 问题的方式,因为您并不总是希望在 Flutter 中为您的小部件提供密钥(注意可空的 Key? 类型):

    class Foo extends StatelessWidget {
      const Foo({Key? key}): super(key: key);
    
      // ...
    }
    

    现在,您无需提供密钥即可安全地构造Foo()

    位置参数

    请注意,这同样适用于 位置 参数,即它们可以设为可空或不可空,但是,它们不能用 required 注释,也不能有默认值,因为它们是 总是要求通过。

    void foo(int param1) {} // bar(null) is invalid.
    
    void bar(int? param1) {} // bar(null) is valid.
    

    【讨论】:

    • 类 SectionListTileWidget 扩展 StatefulWidget { final BuildContext tileContext; final IconData tileLeadingIcon;最终颜色 tileLeadingIconColor;最终字符串 tileTitle;最终功能 tileOnTapAction; SectionListTileWidget({需要this.tileContext,需要this.tileLeadingIcon,需要this.tileLeadingIconColor,需要this.tileTitle,需要this.tileOnTapAction}); @override _SectionListTileWidgetState createState() => _SectionListTileWidgetState(); }
    • 我怎样才能使“tileLeadingIconColor”可以为空,这样如果我没有 tileLeadingIconColor (null),那么我可以使用 Colors.green,否则想要使用用户传递的 tileLeadingIconColor。请建议我该怎么做。非常感谢。
    • 我同意你的观点,这是可选的选择:使用required int paramint? param
    【解决方案2】:

    这也是 Dart 添加不可为空特性的主要原因。因为,您将Key 传递给超类,它可能是null,所以您要确保它不为空。您可以做的是根本不使用key 或为其提供默认值或使其成为required。喜欢:

    MyPage({Key key = const Key("any_key")}) : super(key: key);
    

    或者像这样要求key

    MyPage({required Key key}) : super(key: key);
    

    【讨论】:

    • 新的不可为空的关键字将是 required 而不是 @required ?
    • 嗨@iDecode :) 我将奖励你,因为your question 现已合并。我不确定哪种赏金适合 - 我希望这对你有用。
    • @creativecreatorormaybenot 谢谢,但我期待一个更大的,因为你已经获得了 (32 + 61) x 10 = 930 次。我不会对答案说太多,但可以肯定的是这个问题。反正我也不叫你提,全看你自己了。
    • @iDecode 我明白了 ;) 我没有那样想。我的问题是,回头看,质量通常不能证明赏金是合理的,所以我犹豫要不要夸大它。我会看看是否有可能创造另一个赏金,但我不确定。该系统非常严格。
    • @creativecreatorormaybenot 别担心,你是个好人。你应得的。虽然您可以再次创建新的赏金(下次不能少于 300),但请不要。我对你没有任何遗憾:)
    【解决方案3】:

    作为先前@creativecreatorormaybenot 答案的附加信息,您还可以使用默认强制的位置参数(无花括号),因此不可为空。

      void calculate(int factor) {
         // ...
      }
    

    并且在不命名参数的情况下调用:

    calculate(12);
    

    这些类型的参数可以通过这种方式在构造函数中使用:

    class Foo extends StatelessWidget {
      final String myVar;
    
      const Foo(this.myVar, {Key? key}): super(key: key);
    
      // ...
    }
    

    and "后面可以跟命名参数或可选的位置参数(但不能同时跟)",请参阅此处的文档:dart parameters

    关于命名参数和位置参数之间差异的有趣答案:What is the difference between named and positional parameters in Dart?

    【讨论】:

      【解决方案4】:

      如果我从指向 key 的类的 constructor 收到此错误,我会在 Key 前面添加一个“?”标记,例如这个:

      const ClassName({Key? key}) : super(key: key);
      

      '?'表示可以是nullable

      【讨论】:

        【解决方案5】:

        为Eg添加所需的功能

        required Key key,
            required this.id,
            required this.name,  
            required this.code,  
            required this.img,  
            required this.price,
            required this.promotionPrice,
            required this.size,
            required this.color,
        

        【讨论】:

          猜你喜欢
          • 2022-07-11
          • 2022-06-14
          • 2021-06-24
          • 2021-10-28
          • 2021-11-12
          • 2022-01-03
          • 2022-01-20
          • 1970-01-01
          相关资源
          最近更新 更多