【问题标题】:Flutter required keywordFlutter 必填关键字
【发布时间】:2019-06-08 11:03:02
【问题描述】:

我不太明白required 的工作原理。例如我看过这段代码:

class Test{
  final String x;
  Test({
    required this.x
  });

  factory Test.initial(){
    return Test(x: "");
  }
}

但是required 应该在这里做什么呢?似乎它使可选参数成为非可选参数。

【问题讨论】:

    标签: flutter dart required dart-null-safety


    【解决方案1】:

    @required 是一个注释,它将创建一个警告,让您记住命名参数对于类按预期工作是必需的。 它不会产生编译错误,至少据我所知。

    【讨论】:

    • 但是如果该参数是必需的,为什么要设置为可选参数?
    • 主要是为了代码的可读性。读取对象实例的人无法快速理解未命名的参数。
    【解决方案2】:

    Dart 2.12(空安全):

    从 Dart 2.12 开始,@required 注释现在被 required 关键字替换。如果其他人必须将某些值传递给它,您应该标记您的字段required

    例如:

    class Foo {
      final int a; // Mandatory? Use 'required'
      final int b; // Not mandatory? Don't use 'required'
    
      Foo({
        required this.a, // Marked 'required'
        this.b = 1, 
      });
    }
    

    用法:

    Foo(); // Error: 'a' is required
    Foo(a: 0); // Good
    Foo(a: 0, b: 1); // Good
    

    【讨论】:

    • 即使我没有提到注解,也必须传递参数,因为默认构造函数被此构造函数重载。那它有什么用呢?
    • @NullByte08 我没听清楚,如果你不使用@required 注释它,你不需要将任何值传递给a
    • 不,即使没有注解@required,也需要将值传递给a
    • @NullByte08 如果您能发布一个包含此详细信息的问题,我会很高兴,我可以为您提供更好的帮助。
    • @NullByte08 新建问题有问题吗?
    【解决方案3】:

    @required 限制您在创建 Class 对象时传递 @required 标记的参数。例如,在显示对话框时,您可以根据需要标记上下文,因为没有有效上下文就无法显示对话框。但是,你不应该过度使用它。

    【讨论】:

      【解决方案4】:

      更新

      从 Dart 2.12 开始,required 关键字替换了 @required meta 注释。有关详细信息,请查看official FAQ。以下答案已更新以反映此安全性和 null 安全性。

      默认需要的参数

      类构造函数或函数的参数默认是必需的。

      class Test {
        final String x;
        Test(this.x);
      }
      

      你不能这样做:

      final value = Test(); 
      // 1 positional argument(s) expected, but 0 found.
      

      你必须这样做:

      final value = Test('hello');
      

      可选的命名参数

      但是,如果用花括号将参数括起来,除了成为命名参数之外,它还成为可选参数。

      由于它是可选的,因此该属性必须可以为空,如下所示:

      class Test {
        final String? x;
        Test({this.x});
      }
      

      或者它必须有一个像这样的默认值:

      class Test {
        final String? x;
        Test({this.x = ''});
      }
      

      所以现在可以了:

      final value = Test(); 
      

      这是这样的:

      final value = Test(x: 'hello'); 
      

      必需的命名参数

      有时您不想让参数为null,并且没有自然的默认变量。在这种情况下,您可以在参数名称前添加 required 关键字:

      class Test {
        final String x;
        Test({required this.x});
      }
      

      这已经不行了:

      final value = Test(); 
      // The named parameter 'x' is required, but there's no corresponding argument.
      

      但这仍然没问题:

      final value = Test(x: 'hello');
      

      【讨论】:

        【解决方案5】:

        简短回答:命名参数在 Dart 中默认是可选的。为了便于使用,我们更喜欢使用它们而不是位置参数。在这种情况下,命名参数也可能会一直保持一些值(non-nullable)——从初始化本身开始。因此,双重努力。

        如果值是编译时常量,他可以使用参数的默认值初始化而不是“必需”,而这里似乎不是这种情况。

        位置参数可以是必填的,也可以是可选的,我们在调用时按顺序传递。以下是所需位置参数的用法示例:

        class Object{
          String name;
          int value;
          
          Object(this.name, this.value=100); //auto type inference
        }
        
        final one = Object("Name here", 50); // All parameters are needed to call.
        

        命名参数是另一种类型的可选参数。 Flutter API 使用命名参数,在我们的 UI 代码中,最好使用命名参数而不是位置参数。原因是阅读代码或稍后在代码的几个部分调用构造函数时的可读性和清晰度。您会看到所有小部件、样式都是如此。因为如果它是定位的,那么在调用大量将要使用的方法时很难跟踪它们,并且动态类型推断也可能在起作用。

        void display({required String name, int value1, int value2=100}) {...;} //named params
        
        display(value1: 50, name: "Calculated name");
        

        注意: 如果存在,则必须先出现所需的位置参数。 可以跟随命名或可选的位置参数(不能同时跟随)。

        String say(String from, String msg, [String? device]) { //req. pos params and opt pos params.
          var result = '$from says $msg';
          if (device != null) {
            result = '$result with a $device';
          }
          return result;
        }
        
        assert(say('Bob', 'Howdy') == 'Bob says Howdy');
        

        【讨论】:

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