You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart语言中const与final关键字的区别是什么?

Dart中const与final的核心差异详解

Alright, let's break down the key differences between const and final in Dart—this is a super common question, and getting this right will save you a ton of confusion when writing immutable code!

1. 初始化时机:编译时确定 vs 运行时惰性初始化

  • const:值必须在编译阶段就完全确定,它是真正的编译时常量。这意味着你不能用任何需要运行时计算的值来初始化const变量,比如函数返回值、当前时间、用户输入等。
  • final:值在第一次被使用时才初始化(惰性加载),属于运行时常量。只要赋值后不再修改,你完全可以用运行时生成的结果来初始化final变量。

举个直观的例子:

// ✅ 合法:final允许运行时动态赋值
final currentTime = DateTime.now();

// ❌ 报错:DateTime.now()是运行时方法,无法在编译时确定值
const invalidTime = DateTime.now();

2. 不可变性深度:共享实例 vs 独立实例

两者都保证变量赋值后不可修改,但const的不可变性更彻底:

  • const:对应的对象是编译时常量实例,所有使用相同参数创建的const对象会共享同一个内存地址,相当于全局单例。
  • final:对应的对象是运行时创建的独立实例,即使参数完全相同,每个final实例都是各自独立的(除非你刻意复用对象引用)。

看代码对比:

class Movie {
  final String title;
  const Movie(this.title); // const构造函数,要求参数为编译时常量
}

// 两个const实例,参数相同 → 指向同一个对象
const inception = Movie("Inception");
const inception2 = Movie("Inception");
print(inception == inception2); // 输出 true

// 两个final实例,参数相同 → 是不同的对象(默认比较引用)
final interstellar = Movie("Interstellar");
final interstellar2 = Movie("Interstellar");
print(interstellar == interstellar2); // 输出 false

3. 使用场景的明确区分

优先用const的场景:

  • 固定不变的编译时常量:比如常量字符串、固定数值、预定义配置项
    const maxLoginAttempts = 5;
    const appVersion = "1.0.0";
    
  • 不可变的常量集合(列表、映射等),且集合内元素都是编译时常量
    const primaryColors = ["#FF0000", "#00FF00", "#0000FF"];
    
  • 创建可共享的常量对象,减少内存开销(比如频繁使用的配置类实例)

优先用final的场景:

  • 运行时确定但后续不可变的值:比如API返回数据、用户输入、设备唯一标识
    final userProfile = await fetchUserProfile();
    final deviceId = generateUniqueDeviceId();
    
  • 类的实例字段,每个实例需要拥有独立的不可变属性
    class Order {
      final String orderId;
      final double totalAmount;
      Order(this.orderId, this.totalAmount); // 每个订单的ID和金额都是独立且不可变的
    }
    

4. 额外细节:const上下文的自动推断

在const上下文中(比如const集合、const构造函数的参数里),你可以省略子元素的const关键字,Dart会自动推断为const:

// 下面两行代码完全等价
const movies = [const Movie("Inception"), const Movie("Interstellar")];
const movies = [Movie("Inception"), Movie("Interstellar")]; // const上下文自动推断子元素为const

而final没有这种上下文推断,你需要显式创建集合或对象。


内容的提问来源于stack exchange,提问作者Ishmal Ijaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:06:58