Flutter 是一个使用 Dart 语言构建的 UI 工具包,因此它完全遵循 Dart 的语法和规则。Dart 中的 const
是语言层面的特性,而 Flutter 因其声明式 UI 和频繁重建的特性,将 const
的效能发挥到了极致。
Dart 中的 const
(语言层面)
在 Dart 语言中,const
用于创建编译时常量。它的核心特性如下:
1. 编译时确定
编译时确定:const
变量的值必须在代码编译时就能完全确定。它不能是运行时才能计算出来的值。
// 正确示例
const int a = 1;
const double b = 1.0 + 2.0; // 编译器能计算这个结果
const List<int> c = [1, 2, 3];// 错误示例
var currentTime = DateTime.now();
const d = currentTime; // 错误!DateTime.now()是运行时值
const e = someFunction(); // 错误!函数返回值是运行时值
2. 规范化和唯一性
规范化和唯一性:在程序整个生命周期中,相同的 const
表达式只会被计算一次,并在内存中创建唯一的一个实例。
const list1 = [1, 2];
const list2 = [1, 2];
const list3 = [1, 2];print(identical(list1, list2)); // 输出:true
// identical 检查两个引用是否指向同一个对象
// list1, list2, list3 都是同一个实例
3. 深度不可变
深度不可变:const
构造的对象及其所有字段都必须是不可变的(final
)。一旦创建,就无法更改。
const list = [1, 2, 3];
list.add(4); // 运行时报错:Cannot add to an unmodifiable list
4. 递归的 const
递归的 const
:要创建一个 const
的集合(如 List、Map、Set),其所有元素也必须是编译时常量。
const list = [1, 2, [3, 4]]; // 内部嵌套的列表 [3,4] 也必须是 const
Flutter 中的 const
(应用层面)
Flutter 完全使用 Dart 语言,因此上面的所有规则都适用。Flutter 中 const
的特殊之处在于它的应用场景和带来的巨大性能 benefits。
为什么 const
在 Flutter 中如此重要?
因为 Flutter 的 UI 是通过嵌套的 Widget 树来构建的,而 build
方法会因状态变化、动画等而被非常频繁地调用(每秒60/120次)。每次调用 build
都会创建一棵新的 Widget 树。
没有
const
的情况:Widget build(BuildContext context) {return Container(child: Text('Hello'), // 每次build都创建一个新的Text实例); // 每次build都创建一个新的Container实例 }
内存压力:创建大量短暂的 Widget 实例。
GC 压力:垃圾回收器需要频繁工作,可能引起界面卡顿。
Diff 效率低:Flutter Framework 需要比较新旧 Widget 树。即使UI没变,新创建的实例也会让框架做更多比对工作。
使用
const
的情况:Widget build(BuildContext context) {return const Container(child: Text('Hello'), // 永远是内存中同一个实例); // 永远是内存中同一个实例 }
零内存开销:Widget 实例在编译时即被创建,
build
方法只是复用它们。无 GC 压力:不产生垃圾对象。
极速 Diff:Flutter Framework 看到
identical(oldWidget, newWidget) == true
,会直接跳过这个节点及其整个子树的比对,大幅提升效率。
对比总结:Dart const
vs. Flutter const
特性 | Dart 中的 const (通用概念) | Flutter 中的 const (具体应用) |
---|---|---|
本质 | 语言关键字,用于创建编译时常量 | 就是 Dart 的 const ,主要用于构建 Widget 和相关类 |
目的 | 保证不可变性、实现数据共享 | 性能优化:减少重建开销,提升应用流畅度 |
主要应用对象 | 基础类型(int, String)、集合、自定义类 | Widget、EdgeInsets、BorderRadius、Colors、TextStyle 等 |
核心 benefit | 保证程序正确性、节省内存 | 减少内存分配、减轻GC压力、加快渲染管线中的Diff过程 |