题记:不到最后时刻,千万别轻言放弃,无论结局成功与否,只要你拼博过,尽力过,一切问心无愧
本文描述 Dart 中 const 关键字与 final 关键字的基本使用知识点以及对比区别
1 const 、final 使用场景
1.1 final
final 用来修饰变量 只能被赋值一次,在运行时赋值,所谓运行时 就是当程序执行到这块代码时才会对final 修饰的变量进行赋值。
应用场景一如下图所示,当 final 使用在类中时,在声明变量时,你必须对其初始化赋值
当 final 运用在 StatefulWidget 中时,用来修饰变量时:
这种情况使用 final 修饰的变量看似没有进行初始化赋值,但是不违背 final 修饰的变量在运行时赋值的理解,因为只有当定义的 StatefulWidget 被初始化使用时,这里 final 修饰的变量才会被赋值,当然也是赋值一次。
所以结论是 :final 可用来修饰变量,修饰的变量在运行时被赋值,只可被赋值一次,所以修饰的变量内容也称为常量。
核心思想是:运行时赋值、只能被赋值一次
1.2 const 的使用场景
const 可用来修饰变量、修饰常量构造函数,修饰的变量只可被赋值一次。
const 可用来修饰的变量只可赋值一次,const 修饰的变量会在编译器以至于应用整个生命周期内都是不可变的常量,在内存中也只会创建一次,之后的每次调用都会复用第一次创建的对象。
///全局常量 声明
const String name = "张三";
class TestPage2 {
///类常量 规范要求必须使用 static 修饰
static const String name = "张三";
void test(){
///方法块常量
const String name = "张三";
}
}
const 可用来修饰常量构造函数,常用于定义枚举类型,如下代码清单 1-2-1 所示
/// 代码清单 1-2-1
///订单类型
class OrderStatus {
static const OrderStatus notDeliver = const OrderStatus("待发货",1);
static const OrderStatus hasBeenShipped = const OrderStatus("已发货",2);
static const OrderStatus haveTheGoods = const OrderStatus("已收货",2);
const OrderStatus(this.statusName,this.statusNumber);
final String statusName;
final int statusNumber;
}
使用如下 代码清单 1-2-2 所示:
/// 代码清单 1-2-2
class TestClass5{
///判断订单类型
void test(OrderStatus orderStatus){
switch (orderStatus) {
case OrderStatus.notDeliver:
break;
case OrderStatus.hasBeenShipped:
break;
case OrderStatus.haveTheGoods:
break;
default:
break;
}
}
2 final 与 const 的不同点
2.1 final 与 const 修饰的变量取值时机不同
所谓取值时机不同,指的是 const 修饰的变量是在编译时已确定下来的值,而 final 修饰的变量是在运行时才确定下来的。
const 修饰的变量是在编译期,程序运行前就有确定值。
使用 const 修饰的常量的值,必须由可在编译时可计算出结果的。对于在运行时需要获取的值是不可修饰的,如下图所示:
2.2 应用范畴不同
final 只可用来修饰变量,
const 关键字即可修饰变量也可用来修饰 常量构造函数
2.3 相同内容对象创建不同
如下代码清单 2-3-1 ,虽然创建了两个对象list1和list2,但是内容一致且都是const对象,所以其指向的是同一对象:
/// 代码清单 2-3-1
///单元测试
test(" 测试1 ", () {
const List<int> list1 = [1, 2, 3];
const List<int> list2 = [1, 2, 3];
// 输出结果为true 比较的是指针指向
print(list1 == list2);
// 输出结果为true 比较指针指向同时也比较内容
print(identical(list1, list2));
});
如下代码清单 2-3-2 ,final声明的变量,即使内容相同,也是重新创建新的对象:
/// 代码清单 2-3-2
///单元测试
test(" 测试2 ", () {
final List<int> list1 = [1, 2, 3];
final List<int> list2 = [1, 2, 3];
// 输出结果为false ⽐较的是指针指向
print(list1 == list2);
// 输出结果为false ⽐较指针指向同时也⽐较内容
print(identical(list1, list2));
});