Flutter所需关键字

uyto3xhc  于 2023-03-31  发布在  Flutter
关注(0)|答案(6)|浏览(151)

我不太明白required是如何工作的。例如,我看到了以下代码:

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

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

但是required在这里应该做什么呢?看起来它让一个可选参数变成了一个非可选参数。

xtupzzrd

xtupzzrd1#

更新

从Dart 2.12开始,required关键字取代了@requiredmeta注解。有关详细信息,请查看official FAQ。以下答案已更新,以反映this和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 = ''});
}

现在这样就OK了:

final value = Test();

还有这个

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

必选命名参数

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

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

现在已经不OK了:

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

但这仍然很好:

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

6qqygrtg2#

Dart 2.12(null safety):

从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
7cwmlq89

7cwmlq893#

@required是一个注解,它会创建一个警告,提醒你记住命名参数是类按预期工作所必需的。它不会产生编译错误,至少就我所知。

osh3o9ms

osh3o9ms4#

@required限制你在创建Class的对象时传递@required标记的参数。例如,在显示对话框时,你会将上下文标记为required,因为如果没有有效的上下文,你就不能显示对话框。但是,你不应该过度使用它。

dsekswqp

dsekswqp5#

简短回答:**命名参数在Dart中默认是可选的。**为了便于使用,我们更喜欢使用它们而不是位置参数。在这种情况下,命名参数也可能会一直保持某个值(non-nullable)-从初始化本身开始。需要使用required关键字来强制传递值,同时具有命名参数的可读性。因此,双重工作。
他可以为这些参数使用默认值,但这里可能不需要。
位置参数可以是必选的,也可以是可选的,我们在调用的时候按照顺序传递。下面是必选位置参数的用法示例:

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代码中,首选使用命名参数而不是位置参数。原因是阅读代码或稍后在代码的几个部分调用构造函数时的可读性和清晰度。您可能会看到所有Widget都是这种情况,因为如果它是位置的,那么在调用时很难跟踪它们,因为会使用大量的方法,而且动态类型推断也可能在起作用。

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');
wnvonmuf

wnvonmuf6#

移除
必需的
在构造函数中。请改为
int x;
因此,它变成:

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

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

相关问题