题目
解释 Dart 中 final 和 const 的区别及使用场景
信息
- 类型:问答
- 难度:⭐
考点
变量声明,不可变性,编译时常量
快速回答
核心区别:
final声明运行时常量,值在运行时确定且只能赋值一次const声明编译时常量,值必须在编译时确定
使用场景:
- 用
final修饰运行时计算的不可变值 - 用
const修饰编译时已知的常量值或创建常量集合
1. 核心原理说明
final:
- 表示单次赋值的变量(运行时常量)
- 值在运行时确定(如函数返回值、API 响应)
- 内存中不强制共享同一实例
const:
- 表示编译时常量
- 值必须在编译时完全确定(如字面量、数学表达式)
- 相同值的常量会共享内存实例
2. 代码示例对比
// final 示例
final currentTime = DateTime.now(); // 运行时确定值 ✅
final list1 = [1, 2];
list1.add(3); // ❌ 错误!final 只保证引用不变,但对象内容可变
// const 示例
const pi = 3.14; // 编译时确定值 ✅
const list2 = [1, 2];
list2.add(3); // ❌ 错误!const 创建的是完全不可变集合
// 混合场景
final a = const [1, 2]; // 正确:运行时变量指向编译时常量
const b = DateTime.now(); // ❌ 错误!值无法在编译时确定3. 最佳实践
- 优先使用
const创建常量集合,提升性能:const list = [1, 2, 3]; // 比 final 更高效 - 类构造函数声明为 const 以创建编译时常量对象:
class Point { const Point(this.x, this.y); } - API 响应等运行时数据使用
final
4. 常见错误
- 尝试修改 const/final 变量:
const c = 5; c = 10; // ❌ 编译错误 - 在 const 中使用运行时值:
const n = 1 + 2; // ✅ 合法(编译时可计算)
const m = getValue(); // ❌ 非法 - 混淆对象可变性:
final list = [1, 2];
list = [3, 4]; // ❌ 不能重新赋值
list.add(3); // ✅ 但会改变原对象!
5. 扩展知识
- 内存优化:const 实例在内存中只存在一份,例如:
identical(const [1], const [1]); // true ✅ - const 构造函数:当类所有字段都是 final 且构造函数用 const 修饰时,可创建编译时常量对象:
const p1 = Point(0,0);
const p2 = Point(0,0);
print(identical(p1, p2)); // true ✅ - Dart 3 新特性:新增
final类成员变量初始化语法:class Circle {
final double radius;
Circle(this.radius); // 简写初始化
}