简体   繁体   English

带有所需参数的 Dart 类构造函数,而不是初始化形式

[英]Dart class constructor with required arguments while not initializing formal

I have the following basic class with its constructor in Dart:我在 Dart 中有以下基本类及其构造函数:

class ChartData {
  String? name;
  Color? color;
  Duration? duration;
  ChartData(
      String name, List rgbo, Duration duration) {
    this.name = name;
    this.color = Color.fromRGBO(rgbo[0], rgbo[1], rgbo[2], rgbo[3]);
    this.duration = duration;
  }
}
  1. How can I make it so that the constructor arguments are required, and the class arguments are non-nullable thus don't need any null safety?我怎样才能使它需要构造函数参数,并且类参数不可为空,因此不需要任何空安全性? I'm aware of the keyword required , but from what I understand it works only for initializing formal class constructors.我知道关键字required ,但据我了解,它仅适用于初始化正式的类构造函数。

  2. How could we use initializing formal for this class, especially regarding constructing the color class argument?我们如何为这个类使用初始化形式,尤其是在构造颜色类参数方面?

First of all, you should use an initializer list to initialize the fields, not do assignments in the constructor body.首先,您应该使用初始化列表来初始化字段,而不是在构造函数主体中进行赋值。 Dart is like C++ in that regard, not Java. Dart 在这方面类似于 C++,而不是 Java。

class ChartData {
  final String name;
  final Color color;
  final Duration duration;
  ChartData(String name, List<int> rgbo, Duration duration)
      : this.name = name,
        this.color = Color.fromRGBO(rgbo[0], rgbo[1], rgbo[2], rgbo[3]),
        this.duration = duration;
  
}

This change allows your fields to be final and non-nullable, because now they are initialized before they can ever be read.此更改允许您的字段是最终的且不可为空,因为现在它们在被读取之前已被初始化。 Your arguments are required.你的论点是必需的。 They already were, but they still are.他们已经是,但他们仍然是。

If you want to use initializing formals, and you do, you can replace an initializer list entry of the form this.name = name (or name = name , because the this is already optional) with a parameter of the form this.name :如果你想使用初始化形式,你可以用 this.name 形式的参数替换this.name this.name = name (或name = name ,因为this已经是可选的)形式的初始化列表条目:

class ChartData {
  final String name;
  final Color color;
  final Duration duration;
  ChartData(this.name, List<int> rgbo, this.duration)
      : color = Color.fromRGBO(rgbo[0], rgbo[1], rgbo[2], rgbo[3]);
}

The color parameter cannot be an initializing formal because it doesn't store the argument directly into the field. color参数不能是初始化形式,因为它不会将参数直接存储到字段中。 Just keep that as an initializer list entry instead.只需将其保留为初始值设定项列表条目即可。

This works, the fields are final and non-nullable, the parameters are required and non-nullable, and you use initializing formals where possible.这是可行的,字段是最终的且不可为空,参数是必需的且不可为空,并且您可以在可能的情况下使用初始化形式。

You asked about required .你问了required That modifier works with named parameters, and your parameters are positional.该修饰符适用于命名参数,并且您的参数是位置参数。 If you wanted them to be named instead, you could write it as:如果您希望它们被命名,您可以将其写为:

class ChartData {
  final String name;
  final Color color;
  final Duration duration;
  ChartData(
      {required this.name, required List<int> rgbo, required this.duration})
      : color = Color.fromRGBO(rgbo[0], rgbo[1], rgbo[2], rgbo[3]);
}

The {...} surrounding the parameters makes them named.参数周围的{...}使它们命名。 Required named parameters need a required in front, named parameters default to being optional.必需的命名参数需要在前面加上一个required的,命名参数默认是可选的。 Whether you like required named parameters or not is a matter of taste.您是否喜欢必需的命名参数是个人喜好问题。 Some hate writing and reading the extra name, others prefer it because they find it easier to read.有些人讨厌写和读额外的名字,有些人更喜欢它,因为他们发现它更容易阅读。 Either version works.任何一个版本都有效。

  1. To set the arguments to non-null, you must add required to each argument in a constructor.要将参数设置为非 null,您必须将required添加到构造函数中的每个参数。

  2. If you want to initialize the arguments, you could call the class and set the values.如果要初始化参数,可以调用该类并设置值。 Also you can initialize in some initState()您也可以在一些 initState() 中进行初始化

For example:例如:

class ChartData {
    String name;
    Color color;
    Duration duration;

  ChartData({
    required this.name,
    required this.color,
    required this.duration
});
}

class OtherClass extends StatelessWidget {

  //initialize
  final chartData = ChartData(
      name: "name1",
      color: Color.fromRGBO(38, 38, 38, 0.4),
      duration: const Duration(seconds:15));

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM