我注意到可以在 Dart 中创建一个 const 构造函数。在文档中,它说这个const词用于表示编译时间常数。
const
我想知道当我使用const构造函数创建对象时会发生什么。这是否像一个在编译时始终相同且可用的不可变对象?构造函数的概念const实际上是如何工作的? const 构造函数与 常规 构造函数有何不同?
const 构造函数创建一个“规范化”实例。
也就是说,所有常量表达式都开始规范化,然后这些“规范化”符号用于识别这些常量的等价性。
规范化:
将具有多个可能表示的数据转换为“标准”规范表示的过程。这可以用来比较不同表示的等价性,计算不同数据结构的数量,通过消除重复计算来提高各种算法的效率,或者可以施加有意义的排序顺序。
这意味着 const 表达式 likeconst Foo(1, 1)可以表示任何可用于在虚拟机中进行比较的可用形式。
const Foo(1, 1)
VM 只需要按照它们在这个 const 表达式中出现的顺序来考虑值类型和参数。而且,当然,它们被减少以进行优化。
具有相同规范化值的常量:
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 中规范化(表示)的真实形式;
#Foo#int#1#int#1
但真正的规范化形式必须是“标准”的规范表示。