我注意到可以在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中规范化(表示)的真正形式;

但真正的规范化形式必须是"标准"的规范表示.

Dart相关问答推荐

根据 Id 比较两个不同的 List

如何判断一个数字是否是dart中另一个数字的倍数?

angular.dart NgTwoWay 和 NgAttr 已弃用?

ListView 不会刷新,而附加列表会刷新 (Flutter)

当 ng-repeat 嵌套在 AngularDart 中时访问外部 $index

停止从事件侦听器内部侦听事件

VS Code 无法识别 Flutter 中的单元测试

dart 中 call() 的实现是什么?

Dart 捕获 http 异常

如何在flatter中使用SQFlite更新数据库表

'Future' 的实例而不是显示值

Flutter 错误:The _ScaffoldLayout custom multichild layout delegate forgot to lay out the following child

Flutter /dart 错误:参数类型'Future'不能分配给参数类型'File'

如何仅从 DateTime.now() 中提取时间;

如何判断 Dart NNBD 中的泛型类型是否可以为空?

Dart 中的抽象基类

具有 Maps 的 Null 感知运算符

Dart 中的异步可迭代映射

Dart 脚本会在浏览器中本地运行吗?

Angular.js 和 Angular.dart 的区别?