小编典典

const 构造函数实际上是如何工作的?

all

我注意到可以在 Dart 中创建一个 const 构造函数。在文档中,它说这个const词用于表示编译时间常数。

我想知道当我使用const构造函数创建对象时会发生什么。这是否像一个在编译时始终相同且可用的不可变对象?构造函数的概念const实际上是如何工作的?
const 构造函数与 常规 构造函数有何不同?


阅读 84

收藏
2022-07-18

共1个答案

小编典典

const 构造函数创建一个“规范化”实例。

也就是说,所有常量表达式都开始规范化,然后这些“规范化”符号用于识别这些常量的等价性。

规范化:

将具有多个可能表示的数据转换为“标准”规范表示的过程。这可以用来比较不同表示的等价性,计算不同数据结构的数量,通过消除重复计算来提高各种算法的效率,或者可以施加有意义的排序顺序。


这意味着 const 表达式 likeconst 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 中规范化(表示)的真实形式;

但真正的规范化形式必须是“标准”的规范表示。

2022-07-18