Dart const常量构造函数详解

作者:野猿新一 来源:blog.csdn.net 更新时间:2023-05-25 21:55

专业解释: https://stackoverflow.com/questions/21744677/how-does-the-const-constructor-actually-work/21746692#21746692

常量构造函数总结如下几点:

  • 常量构造函数需以const关键字修饰
  • 它的类不能有任何非final字段(我们在编译时“知道”的值不能在以后更改)
  • 构建常量实例必须使用定义的常量构造函数
  • 如果实例化时不加const修饰符,即使调用的是常量构造函数,实例化的对象也不是常量实例
  • const构造函数不能有主体(没有语句执行!),

下面结合实例,对以上几点加以说明

 

正确的常量构造函数定义

根据以上的总结,定义一个Point类,包含一个常量构造函数,注意其成员变量都是final类型,且构造函数用const修饰

class Point {
  final int x;
  final int y;
  const Point(this.x, this.y);
}
 常量构造函数需以const关键字修饰

如下代码定义一个const对象,但是调用的构造方法不是const修饰的,则会报The constructor being called isn't a const constructor.错误

 
void main() {
  const point = Point(1, 2); // 报错
}
 
class Point {
  final int x;
  final int y;
  Point(this.x, this.y);
}

const构造函数必须用于成员变量都是final的类

如下代码中成员变量x为非final,会报Can't define a const constructor for a class with non-final fields.错误

class Point {
  int x;
  final int y;
  const Point(this.x, this.y);
}

构建常量实例必须使用定义的常量构造函数

如下代码,定义一个const对象,但是调用的却是非常量构造函数,会报The constructor being called isn't a const constructor.错误

void main() {
  var point = const Point(1, 2); // 报错
  print(point.toString());
}
 
class Point {
  int x;
  int y;
  Point(this.x, this.y); // 非const构造函数
  
  String toString() {
    return 'Point(${x}, ${y})';
  }
}

如果实例化时不加const修饰符,即使调用的是常量构造函数,实例化的对象也不是常量实例

如下代码,用常量构造函数构造一个对象,但是未用const修饰,那么该对象就不是const常量,其值可以再改变

void main() {
  Test a = const Test(1);
  Test b = const Test(1);
  Test c = Test(1);
  assert(identical(a, b));  //true
  assert(identical(b, c));  //false
}

class Test<T> {
  final T a;
  const Test(this.a);
}