侧边栏壁纸
博主头像
colo

欲买桂花同载酒

  • 累计撰写 1823 篇文章
  • 累计收到 0 条评论

解释 Dart 中 final 和 const 的区别及使用场景

2025-12-12 / 0 评论 / 4 阅读

题目

解释 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); // 简写初始化
    }