Dart 中的 const 关键字

2023-05-29  本文已影响0人  teletian

const 修饰内置数据类型

const 修饰内置数据类型,那么之后就不允许修改了,否则编译阶段会报错。

void main() {
  const int a = 1;
  // a = 2;
  const double d = 1.0;
  // d = 2.0;
  const String str = "hello";
  // str = "world";
  const List list = [1, 2, 3];
  // list = [4, 5, 6];
}

const 修饰自定义数据类型

如果要用 const 修饰自定义数据类型,那么它的构造方法也必须加 const,否则编译阶段会报错。

void main() {
  // 此处编译报错:Const variables must be initialized with a constant value.
  const Person p = Person("Jack", 11);
}

class Person {

  String name;
  int age;

  Person(this.name, this.age);
}

构造方法加上 const 之后,编译器提示成员变量必须是 final 的。

void main() {
  const Person p = Person("Jack", 11);
}

class Person {

  String name;
  int age;

  // 此处编译报错:Can't define a const constructor for a class with non-final fields.
  const Person(this.name, this.age);
}

继续给成员变量加 final 关键字,发现没有编译错误了。

void main() {
  const Person p = Person("Jack", 11);
  // p = Person("Rose", 12) // 不可以修改
}

class Person {

  final String name;
  final int age;

  const Person(this.name, this.age);
}

注意:const 要加到前面才可以将变量的值设置为不可以被修改,如果 const 加到后面,变量的值还是可以被修改的。(那么,const 加到后面有什么意义呢?可以节省内存空间,下文有具体介绍,这里就不解释了)

void main() {
  const Person p = Person("Jack", 11);
  // p = Person("Rose", 12) // 不可以修改

  Person p2 = const Person("Jack", 11);
  p2 = const Person("Rose", 12); // 仍然可以修改
}

class Person {

  final String name;
  final int age;

  const Person(this.name, this.age);
}

类中定义 const 的成员

类中定义 const 的成员,必须要加 static 关键字,这是固定的定义常量的写法。

class Person {

  // static const 定义常量
  static const String TAG = "MyTag";

  final String name;
  final int age;

  const Person(this.name, this.age);
}

const 节省内存空间

来看看下面这个例子:

void main() {
  for (var i = 0; i < 10; i++) {
    Person p = const Person("Jack", 11);
    print(p.hashCode);
  }
}

class Person {

  static const String TAG = "MyTag";

  final String name;
  final int age;

  const Person(this.name, this.age);
}

for 循环中创建了 10 个 Person 对象,打印出来的 hash code 却是一模一样,这就说明了 10 次用的同一个对象,这样的好处就是节省内存空间。

这个在 flutter 中也很常用,对于一些不需要修改的控件,定义成 const,不管调用多少次,都是同一份内存空间:

const Text("Hello World!")

const 是编译期常量

const 是编译器常量,不能在其中使用只能在运行期间才能确定的变量。以下代码编译出错:

int count = 0;
const Text("次数:$count");

const 层级

如果上层是 const 的,下面的层级必须都是 const 的

  const Padding(
    padding: const EdgeInsets.all(10),
    child: const Text("Hello World"),
  );

子层级的 const 可以省略

  const Padding(
    padding: EdgeInsets.all(10),
    child: Text("Hello World"),
  );

如果外层加了 const,但是子层级中有不能修饰为 const 的控件,编译会报错

const 和 final 的区别

final 修饰的变量在第一次使用时被初始化,之后不允许修改。
const 修饰的变量是一个编译时常量,编译后会发现在用到常量的地方,直接用常量值替换了。

上一篇下一篇

猜你喜欢

热点阅读