常量列表和不可修改列表有什么区别?

  • 本文关键字:列表 区别 修改 常量 dart
  • 更新时间 :
  • 英文 :


我无法在常量列表和不可修改列表中添加/删除/修改元素。那么,如果两者都在做同样的事情,它们之间有什么区别呢?

没有区别,因为稍微夸张一点,没有"const列表";。

在Dart中,常量不是值的属性,而是表达式的属性。

示例:

class Foo {
final int x;
const Foo(this.x);
}
main() {
var foo1 = const Foo(1);
var foo2 = new Foo(1);
print(isConstant(foo1)); // cannot be done.
}

没有办法编写一个通用的isConstant函数来区分使用const创建的对象和使用new创建的对象。运行时系统在某个地方有一个const创建的对象列表(因为它需要它来将另一个const Foo(1)规范化为相同的值(,但值本身不知道它是使用const表达式创建的。

列表文字与基于构造函数的对象创建略有不同,因为非常量文字是可变的,而常量文字不是。相反,const文字会创建一个列表对象,类似于使用List.unmodifiable创建的列表对象。同样,列表对象本身不知道它是使用const [...]还是List.unmodifiable([...])创建的,它只知道它是一个具有特定值集的不可修改列表。

虚拟机实际上对const列表和不可修改列表都使用相同的类(dart2js对所有内容都使用JS Array,但确实以相同的方式将它们标记为固定长度和不可更改(。编译器不必使用同一个类,const列表是如何实现的,这是一个实现细节,但它们只有一个不可修改列表的实现也就不足为奇了,其他任何事情都会浪费。

因此,const列表对象和使用List.unmodifiable创建的列表之间没有区别。它们是同一实现类的实例。

(显然,包含常量列表的常量变量可以在其他常量表达式中使用,并且常量列表文本是规范化的,所以如果在程序中的两个位置写入const [1],它的计算结果是相同的列表对象,但对象本身只是一个不可修改的列表(。

这是有区别的。将const用于List时,只能添加常数值。然而,不可修改列表的情况并非如此。

var foo = 1;
const l1 = [foo]; // Compile-time error
final l2 = List.unmodifiable([foo]); // No error

另一个重要区别是两个相等的const对象保证是相同的(因此它们指向相同的内部对象,因为对象是在编译时构建的(,其中两个不可修改的列表将始终是两个不同的对象:

void main() {
final unmodifiableList1 = List<int>.unmodifiable(<int>[1,2,3]);
final unmodifiableList2 = List<int>.unmodifiable(<int>[1,2,3]);
print(identical(unmodifiableList1, unmodifiableList2)); // false
const constList1 = [1,2,3];
const constList2 = [1,2,3];
print(identical(constList1, constList2)); // true
}

最新更新