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



所以在dartnew关键字设为可选之后,

我们可以用完全相同的语法初始化一个对象,但内部实现不同

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

使用它们的地方是什么?

实际上,工厂构造函数和静态方法之间几乎没有区别。

对于泛型类,它会更改您可以(并且必须(编写类型参数的位置:

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 的操作。

构造函数和静态函数是不同的。通常创建一个命名构造函数,该构造函数返回具有一些预定义值的对象实例。例如,您有一个名为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"});
}

静态类方法的另一个非常有用的功能是,你可以使它们异步,即等待完全初始化,以防这依赖于一些异步操作:

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

区分named constructorstatic function的另一个好处是,在生成的文档中,函数将提交在构造部分或方法部分,这进一步使读者更清楚地了解了它的意图。

在文档的构造函数部分中查找构造函数的人将很容易发现命名的构造函数,而不必也挖掘静态函数部分。

如果类具有最终字段,您可能无法编写命名构造函数,但仍然可以编写静态方法。

在下面的代码中,我们不能使用 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 编译器以某种方式承认相似性,并且不允许同时具有同名的命名构造函数和静态方法。

相关内容

最新更新