变量与常量
Dart 自 2.12 起默认启用空安全(null safety),因此变量在声明时需要明确是否允许为空。下面通过常见声明方式说明差异。
指定类型与类型推断
Dart 是强类型语言,变量一经赋值就确定了类型:
void main() {
String name = 'Dash'; // 显式类型
var age = 10; // 通过首个赋值推断为 int
// age = 'ten'; // ❌ 不能将 String 赋给已推断为 int 的变量
}
dart
未初始化的局部变量必须声明为可空类型或使用 late
关键字:
void main() {
String? nickname; // 可空,初始值为 null
nickname = 'Dash';
late final DateTime createdAt; // 先声明,稍后(只赋值一次)初始化
createdAt = DateTime.now();
}
dart
顶级或类字段若未赋值会默认初始化为 null
,同样需要可空类型才能通过编译。
var
、final
、const
var
:可变变量,由首个赋值推断类型;若需要重新赋不同类型的值,请使用dynamic
。final
:运行时常量,值只能赋一次(类似其它语言的const
引用)。const
:编译期常量,要求值在编译阶段即可确定,可用于声明常量字面量、默认参数等。
void main() {
final now = DateTime.now();
const pi = 3.1415926;
// const 支持嵌套常量集合
const colors = ['red', 'green'];
}
dart
const
可以作用于集合字面量,生成不可变的编译期常量;若只需不可变引用,使用 final
即可。
dynamic
、Object
与 Object?
dynamic
:跳过编译期类型检查,所有成员调用在运行时解析;慎用,建议只在确实无法推断类型时使用。Object
:所有 Dart 类型的非空基类(等同于Object
)。只允许调用Object
定义的成员。Object?
:允许存储任何可空值,常用于不确定类型但仍需保留基本运算的场景。
void main() {
dynamic anything = 'hello';
anything = 42; // ✔️ 允许
Object obj = 'hi';
// obj.trim(); // ❌ Object 上没有 trim,需显式类型转换
if (obj is String) {
print(obj.trim()); // 经过类型守卫后可调用 String 方法
}
}
dart
late
关键字
late
允许延迟初始化非空变量,常见于依赖注入或懒加载:
late final Database db;
Future<void> init() async {
db = await Database.open();
}
dart
late
可与final
/普通变量配合使用。- 访问
late
变量时若未初始化会抛出运行时错误,需确保初始化逻辑先执行。
常量构造与默认值
可以使用常量构造函数配合 const
创建编译期常量实例:
class Point {
final double x;
final double y;
const Point(this.x, this.y);
}
const origin = Point(0, 0);
dart
可选参数的默认值必须是编译期常量,因此统一使用 const
:
void paint({Color color = const Color(0xFFFFFFFF)}) {
// ...
}
dart
示例扩展(沿用早期写法,更新为空安全)
以下示例来自旧版笔记,保留原始思路并按照 Dart 空安全语法做了修正:
void main() {
String? name; // 未赋值的局部变量需声明为可空
print(name); // 输出:null
String userName = 'toimc';
int age = 18;
print('${userName}----$age');
// 通过 var 推断类型后依旧是强类型
var city = 'Shenzhen';
// city = 123; // ❌ 编译错误,类型已推断为 String
var flexible;
flexible = 18;
flexible = '18'; // 未指定类型时,与 dynamic 行为一致
// int 与 double 都是 num 的子类
num score = 95;
score = 95.5;
print(score);
}
dart
dynamic
和 Object
示例:
void main() {
dynamic label = 'toimc';
print(label.runtimeType); // String
label = 18;
print(label.runtimeType); // int
Object anything = 18;
anything = 'Dash';
print(anything);
}
dart
final
/const
在类中的使用:
class User {
final String id; // 只能赋值一次,可在构造函数中设置
final DateTime createdAt;
const User._internal(this.id, this.createdAt);
factory User.newUser(String id) {
return User._internal(id, DateTime.now());
}
}
const originUser = User._internal('system', DateTime.fromMillisecondsSinceEpoch(0));
dart
以上内容覆盖了 Dart 中变量与常量的核心概念,同时保留了旧笔记中的学习例子。后续章节我们将继续深入基础类型、操作符与控制流。
↑