简体   繁体   English

Dart 命名构造函数与 Static 方法更喜欢什么?

[英]Dart Named constructor vs Static method what to prefer?

So after dart made new keyword optional,所以在dart使new关键字可选之后,

we can initialize an object with exact same syntax but different internal implementation .我们可以使用完全相同的语法但不同的内部实现来初始化 object。

class Color {
  int r = 0, g = 0, b = 0;

  Color({this.r, this.b, this.g});

  //Named constructors
  Color.red() //Implementation

  Color.cyan() //Implementation

  // Static Initializers
  static Color red() => //Initialze with parameter

  static Color cyan() => //Initialze with parameter
}

We can use them like this regardless of being it a named constructor or static method :无论named constructor还是static method ,我们都可以这样使用它们:

Color red = Color.red();
Color cyan = Color.cyan();

What is the place to use each of them?使用它们每个的地方是什么?

Constructors and static functions are different.构造函数和 static 函数不同。 You usually create a named constructor that returns an instance of an object with some predefined values.您通常会创建一个命名构造函数,该构造函数返回具有一些预定义值的 object 实例。 For example, you have a class called Person which stores Name and Job .例如,您有一个名为Person的 class 存储NameJob You can create this named constructer Person.doctor(name) which you will return a Person object with Job = 'doctor'您可以创建这个命名构造Person.doctor(name) ,您将返回一个Person object ,其中Job = 'doctor'

 class Person{
  final name;
  final job;

  Person(this.name, this.job);

  Person.doctor(this.name, {this.job = "doctor"});

 }

Static functions or variable persists on all the instance of a class. Static 函数或变量持续存在于 class 的所有实例上。 Let us say, Person has a static variable called count .假设, Person有一个名为count的 static 变量。 You increment the count variable whenever an instance of Person is created.每当创建Person的实例时,就增加 count 变量。 You can call Person.count anywhere later in your code to get the value of count (Number of instances of Person )您可以稍后在代码中的任何位置调用Person.count以获取count的值( Person的实例数)

class Person{
  final name;
  final job;
  static int count;

  Person(this.name, this.job){
    count++;
  }

  Person.doctor(this.name, {this.job = "doctor"});

}

In practice there is little difference between a factory constructor and a static method.实际上,工厂构造函数和 static 方法之间几乎没有区别。

For a generic class, it changes where you can (and must) write a type parameter:对于通用 class,它会更改您可以(并且必须)编写类型参数的位置:

class Box<T> {
  T value;
  Box._(this.value);
  factory Box.withValue(this.value) => Box<T>._(value);
  static Box<T> fromValue<T>(T value) => Box<T>._(value);
}
...
  var box1 = Box<int>.withValue(1);
  var box2 = Box.fromValue<int>(2);

So, for generic classes, factory constructors are often what you want.因此,对于泛型类,工厂构造函数通常是您想要的。 They have the most pleasant syntax.他们有最令人愉快的语法。

For non-generic classes, there is very little difference, so it's mainly about signaling intent.对于非泛型类,差别很小,所以主要是关于信号意图。 And deciding which category the name goes into in the DartDoc.并决定名称在 DartDoc 中属于哪个类别。

If the main objective of the function is to create a new object, make it a constructor.如果 function 的主要目标是创建一个新的 object,则使其成为构造函数。

If the main objective is to do some computation and eventually return an object (even if it's a new object), make it a static function.如果主要目标是进行一些计算并最终返回 object(即使它是一个新对象),请将其设为 static function。 That's why parse methods are generally static functions.这就是为什么parse方法通常是 static 函数。

In short, do what feels right for your API.简而言之,做适合您的 API 的事情。

Another benefit of the distinction between named constructor and static function is that in the documentation generated the function will be either filed in the construction section or the methods section, which further makes it's intentions clearer to the reader. named constructorstatic function之间区别的另一个好处是,在生成的文档中 function 将进一步归档在构造部分或方法部分中,以便读者更清楚地了解。

A person looking for a constructor in the constructor section of the documentation will easily discover the named constructors as opposed to having to also dig through the static functions section too.在文档的构造函数部分中寻找构造函数的人将很容易发现命名的构造函数,而不必也挖掘 static 函数部分。

Another very useful feature of static class methods is that you can make them asynchronous, ie wait for full initialisation in case this depends on some asynchronous operation: static class 方法的另一个非常有用的特性是您可以使它们异步,即等待完全初始化,以防这取决于一些异步操作:

Future<double> getCurrentPrice(String ticker) async {
  double price;
  // for example, fetch current price from API
    price = 582.18;
  return price;
}

class Stock {
      String ticker;
      double currentPrice=0.0;
      
      Stock._(this.ticker);
      
      static Future<Stock> stockWithCurrentPrice(String ticker) async {
        Stock stock = Stock._(ticker);
        stock.currentPrice =  await getCurrentPrice (ticker);
        return stock;
      }
}

void main() async {
  Stock stock = await Stock.stockWithCurrentPrice('AAPL');
  print ('${stock.ticker}: ${stock.currentPrice}');
}

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

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