我注意到可以在DART中创建常量构造函数.在文档中,它说const
个单词用于表示某个编译时间常数.
我想知道当我使用const
构造函数创建一个对象时会发生什么.这像是一个不可变的对象,在编译时总是相同且可用吗?const
构造函数的概念实际上是如何工作的?const构造函数和regular构造函数有何不同?
我注意到可以在DART中创建常量构造函数.在文档中,它说const
个单词用于表示某个编译时间常数.
我想知道当我使用const
构造函数创建一个对象时会发生什么.这像是一个不可变的对象,在编译时总是相同且可用吗?const
构造函数的概念实际上是如何工作的?const构造函数和regular构造函数有何不同?
常量构造函数创建一个"规范化的"实例.
也就是说,所有常量表达式开始规范化,然后使用这些"规范化"符号来识别这些常量的等价性.
Canonicalization:个
将具有多种可能表示的数据转换为"标准"规范表示的过程.这可以用来比较不同表示的等价性,计算不同数据 struct 的数量,通过消除重复计算来提高各种算法的效率,或者使施加有意义的排序顺序成为可能.
这意味着像const Foo(1, 1)
这样的常量表达式可以表示对虚拟机中的比较有用的任何可用形式.
VM只需要按照值类型和参数在此常量表达式中出现的顺序考虑它们.当然,它们是为了优化而减少的.
具有相同规范化值的常量:
var foo1 = const Foo(1, 1); // #Foo#int#1#int#1
var foo2 = const Foo(1, 1); // #Foo#int#1#int#1
具有不同规范化值的常量(因为签名不同):
var foo3 = const Foo(1, 2); // $Foo$int$1$int$2
var foo4 = const Foo(1, 3); // $Foo$int$1$int$3
var baz1 = const Baz(const Foo(1, 1), "hello"); // $Baz$Foo$int$1$int$1$String$hello
var baz2 = const Baz(const Foo(1, 2), "hello"); // $Baz$Foo$int$1$int$2$String$hello
不会每次都重新创建常量.它们在编译时被规范化,并存储在特殊的查找表中(在那里,它们通过其规范签名进行散列),然后从中重用.
附注:
这些样本中使用的表格#Foo#int#1#int#1
仅用于比较目的,并不是Dart VM中规范化(表示)的真正形式;
但真正的规范化形式必须是"标准"的规范表示.