常量构造函数
有些对象是在编译时就可以计算的常量。其中许多是显而易见的字面量,如3.14159、“Hello World”等。
Dart支持用户定义常量对象,如果类的对象不会发生变化,可以构造一个编译时的常量构造函数,定义格式如下:
- 定义所有的实例变量是final
- 使用const声明构造函数
- 不能有函数体,可以有初始化列表
class Point {
final x, y;
const Point(this.x, this.y);
}
main(List<String> args) {
const origin = const Point(0, 0);
// var origin2 = new Point(0, 0); // 这样也是可以的
print(origin.x);
}
在适当的条件下,我们可以生成一个代表原点的Point常量对象。origin变量被声明为常量。我们只能把一个常量赋值给它。常量对象的创建是使用const而不是new。同new表达式一样,const表达式也是调用构造函数,但该构造函数必须是常量构造函数,而且它的参数必须是常量。实际上,Dart要求常量构造函数的参数必须是数字、布尔值或字符串。
我们已经把Point的构造函数声明为常量。这会给类及构造函数加强一些非常严格的限制。我们需要一个状态不可变的类。
此外一个常量构造函数不能有函数体。它可以有一个初始化列表,前提是只计算常量。
回想一下之前的示例,我们不能将类似Point.polar()的构造函数定义为常量,因为它使用了像sqrt()这样的结果不是常量的函数。Point有这样一个构造函数是没有问题的,我们只是不能用const调用它而已。因此任意使用这个构造函数创建的点都不是常量。
我们并不是总需要创建常量。事实上我们仍然可以使用new调用常量构造函数。如果我们这样做,则我们传递的参数不再受限制,但结果不再是常量。
常量的值可以提前计算,只需一次,无需重新计算。Dart程序中的常量是规范化的,一个给定的值只会产生一份常量。