flutter Dart命名构造函数与静态方法哪个更好?

f0ofjuux  于 2023-06-07  发布在  Flutter
关注(0)|答案(5)|浏览(162)

因此,在dart使new关键字成为可选的之后,
我们可以用***完全相同的语法但不同的内部实现***初始化一个对象。

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
}

我们可以像这样使用它们不管named constructor还是static method

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

它们各自的用途是什么?

ippsafx7

ippsafx71#

在实践中,* 工厂 * 构造函数和静态方法之间几乎没有区别。
对于泛型类,它改变了您可以(并且必须)编写类型参数的位置:

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

因此,对于泛型类,工厂构造函数通常是您想要的。他们有最令人愉快的语法。
对于非泛型类,差别很小,所以主要是关于信号意图。并决定该名称在DartDoc中的类别。
如果函数的主要目标是创建一个新对象,则将其设置为构造函数。
如果主要目标是进行一些计算并最终返回一个对象(即使它是一个新对象),请将其设置为静态函数。这就是为什么parse方法通常是静态函数。
简而言之,做你觉得适合你的API的事情。

wqsoz72f

wqsoz72f2#

构造函数和静态函数是不同的。通常创建一个命名构造函数,该构造函数返回具有某些预定义值的对象示例。例如,您有一个名为Person的类,它存储NameJob。您可以创建这个命名的构造函数Person.doctor(name),它将返回一个带有Job = 'doctor'Person对象

class Person{
  final name;
  final job;

  Person(this.name, this.job);

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

 }

静态函数或变量在类的所有示例上保持不变。例如,Person有一个名为count的静态变量。每当创建Person的示例时,就递增count变量。您可以在代码后面的任何地方调用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"});

}
ep6jt1vc

ep6jt1vc3#

静态类方法的另一个非常有用的特性是,你可以使它们异步,即。等待完全初始化,以防这取决于某些异步操作:

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}');
}
ndh0cuux

ndh0cuux4#

named constructorstatic function之间的区别的另一个好处是,在生成的文档中,函数将被提交到构造部分或方法部分,这进一步使读者更清楚它的意图。
在文档的构造函数部分寻找构造函数的人将很容易发现命名的构造函数,而不是还必须通过静态函数部分进行挖掘。

gt0wga4j

gt0wga4j5#

如果类有final字段,你可能不能写一个命名构造函数,但仍然可以写一个静态方法。
在下面的代码中,我们不能有fromHex构造函数,但可以有静态方法:

class Color {
  final int r;
  final int g;
  final int b;

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

  //Color.fromHex(String hex) {...}   //does not compile

  static Color fromHex(String hex) {
    int intColor = int.parse(hex);
    int red = (intColor >> 16) & 0xff;
    int green = (intColor >> 8) & 0xff;
    int blue = (intColor >> 0) & 0xff;
    return Color(r: red, g: green, b: blue);
  }
}

此外,Dart编译器以某种方式承认相似性,并且不允许具有相同名称的命名构造函数和静态方法。

相关问题