Dart 是 Flutter 的编程语言,具备强类型、空安全、AOT/JIT 双模编译等特性。掌握 Dart 是高效 Flutter 开发的前提。
一、空安全机制(Null-Safety)
Dart 2.12 起默认开启空安全,从根本上消除 Null Pointer Exception。
1.1 可空类型 vs 非空类型
dart
String name = 'Flutter'; // 非空,不能赋值 null
String? nickname = null; // 可空,允许为 null
1.2 断言操作符与条件访问
dart
String? text = maybeNull();
// ! 断言非空(请确保确实非空,否则抛出异常)
print(text!.length);
// ?. 安全访问
print(text?.length); // text 为 null 时返回 null
// ?? 空值合并
String result = text ?? 'default';
// ??= 空值赋值
text ??= 'assigned if null';
1.3 Late 变量
dart
// 延迟初始化,声明时不赋值,使用前必须赋值
late String userId;
void init() {
userId = fetchUserId(); // 使用前初始化
}
1.4 空安全与 Flutter 实践
dart
class UserProfile {
final String name; // 必填,非空
final String? avatar; // 可选头像,可为 null
final int age;
const UserProfile({
required this.name, // required 确保调用方必须传入
this.avatar, // 可选参数
required this.age,
});
}
二、异步编程
Dart 采用单线程事件循环 (Event Loop),异步操作通过 Future、Stream 和 async/await 处理。
2.1 Future
Future<T> 代表一个未来会完成的异步操作:
dart
Future<String> fetchUser(int id) async {
// 模拟网络请求
await Future.delayed(const Duration(seconds: 1));
return 'User_$id';
}
// 使用方式一:async/await
void loadUser() async {
try {
final user = await fetchUser(1);
print(user);
} catch (e) {
print('Error: $e');
}
}
// 使用方式二:then/catchError
fetchUser(1)
.then((user) => print(user))
.catchError((e) => print('Error: $e'))
.whenComplete(() => print('Done'));
并发执行多个 Future:
dart
// 并发执行,等待所有完成
final results = await Future.wait([
fetchUser(1),
fetchUser(2),
fetchUser(3),
]);
// 竞速,取最先完成的
final first = await Future.any([
fetchFromServer1(),
fetchFromServer2(),
]);
2.2 Stream
Stream<T> 代表一系列异步事件,适合实时数据(WebSocket、传感器、文件读取):
dart
// 创建 Stream
Stream<int> counter(int max) async* {
for (int i = 0; i < max; i++) {
await Future.delayed(const Duration(seconds: 1));
yield i; // 每秒产生一个值
}
}
// 监听 Stream
final subscription = counter(5).listen(
(value) => print('Value: $value'),
onError: (e) => print('Error: $e'),
onDone: () => print('Stream ended'),
);
// 取消监听(防止内存泄漏)
subscription.cancel();
StreamController(自定义 Stream):
dart
final controller = StreamController<String>();
// 向 Stream 推送数据
controller.sink.add('Hello');
controller.sink.add('Flutter');
// 监听
controller.stream.listen((msg) => print(msg));
// 关闭
await controller.close();
2.3 async / await 最佳实践
dart
// ✅ 推荐:明确 try-catch
Future<void> loadData() async {
try {
final data = await api.fetchData();
setState(() => _data = data);
} on NetworkException catch (e) {
setState(() => _error = e.message);
} finally {
setState(() => _loading = false);
}
}
// ❌ 避免:忘记 await 导致竞态
void badExample() async {
fetchData(); // 没有 await,结果被忽略
}
三、面向对象
3.1 class(类)
dart
class Animal {
final String name;
int _age; // 私有属性(以 _ 开头)
Animal(this.name, this._age); // 简洁构造函数
// 命名构造函数
Animal.unknown() : name = 'Unknown', _age = 0;
// getter
int get age => _age;
// setter
set age(int value) {
if (value >= 0) _age = value;
}
// 实例方法
String describe() => '$name is $_age years old';
@override
String toString() => 'Animal($name, $_age)';
}
// 继承
class Dog extends Animal {
final String breed;
Dog(super.name, super.age, this.breed);
@override
String describe() => '${super.describe()}, breed: $breed';
}
3.2 mixin(混入)
mixin 用于在不使用继承的情况下复用代码:
dart
mixin Flyable {
double altitude = 0;
void fly() {
altitude = 1000;
print('Flying at $altitude m');
}
}
mixin Swimmable {
void swim() => print('Swimming...');
}
// 使用 with 混入多个 mixin
class Duck extends Animal with Flyable, Swimmable {
Duck(super.name, super.age);
}
final duck = Duck('Donald', 3);
duck.fly();
duck.swim();
mixin 限制使用场景:
dart
mixin CanDebug on StatefulWidget {
// 只能被 StatefulWidget 子类使用
void debugState() => print('Debug info');
}
3.3 extension(扩展)
无需修改原始类,给现有类添加方法:
dart
extension StringUtils on String {
bool get isEmail => contains('@') && contains('.');
String capitalize() =>
isEmpty ? this : '${this[0].toUpperCase()}${substring(1)}';
}
extension DateUtils on DateTime {
bool get isToday {
final now = DateTime.now();
return year == now.year && month == now.month && day == now.day;
}
}
// 使用
print('hello@example.com'.isEmail); // true
print('flutter'.capitalize()); // Flutter
print(DateTime.now().isToday); // true
3.4 抽象类与接口
dart
// 抽象类(不能实例化,可以有具体方法)
abstract class Repository<T> {
Future<T?> findById(int id);
Future<List<T>> findAll();
Future<void> save(T entity);
Future<void> delete(int id);
// 非抽象方法(子类可直接继承)
Future<int> count() async {
final all = await findAll();
return all.length;
}
}
// 实现抽象类
class UserRepository extends Repository<User> {
@override
Future<User?> findById(int id) async {
// 具体实现
return await db.query('users', where: 'id = ?', whereArgs: [id]);
}
// ... 其他方法实现
}
// Dart 中 class 本身即接口,可以用 implements 实现
class MockUserRepository implements Repository<User> {
@override
Future<User?> findById(int id) async => null;
// 所有方法必须实现
}
四、集合与泛型
4.1 List(列表)
dart
// 字面量创建
final fruits = ['apple', 'banana', 'cherry'];
// 类型化
final List<int> numbers = [1, 2, 3, 4, 5];
// 常用操作
numbers.add(6);
numbers.addAll([7, 8]);
numbers.remove(1);
numbers.removeAt(0);
// 函数式操作
final evens = numbers.where((n) => n.isEven).toList();
final doubled = numbers.map((n) => n * 2).toList();
final sum = numbers.fold(0, (acc, n) => acc + n);
final sorted = [...numbers]..sort();
// spread operator
final combined = [...list1, ...list2, if (condition) extraItem];
4.2 Map(映射)
dart
final user = {
'name': 'Alice',
'age': 25,
'email': 'alice@example.com',
};
// 安全访问
final name = user['name'] ?? 'Unknown';
// 遍历
user.forEach((key, value) => print('$key: $value'));
final keys = user.keys.toList();
final values = user.values.toList();
// 转换
final upperKeys = user.map((k, v) => MapEntry(k.toUpperCase(), v));
4.3 Set(集合)
dart
final tagSet = <String>{'flutter', 'dart', 'mobile'};
tagSet.add('web');
tagSet.remove('dart');
// 集合运算
final a = {1, 2, 3, 4};
final b = {3, 4, 5, 6};
print(a.union(b)); // {1, 2, 3, 4, 5, 6}
print(a.intersection(b)); // {3, 4}
print(a.difference(b)); // {1, 2}
4.4 泛型约束
dart
// T 必须是 Comparable 的子类型
T findMax<T extends Comparable<T>>(List<T> list) {
return list.reduce((a, b) => a.compareTo(b) > 0 ? a : b);
}
print(findMax([3, 1, 4, 1, 5, 9])); // 9
print(findMax(['banana', 'apple', 'cherry'])); // cherry
// 泛型类
class Cache<T> {
final _store = <String, T>{};
void set(String key, T value) => _store[key] = value;
T? get(String key) => _store[key];
void clear() => _store.clear();
}
final cache = Cache<User>();
cache.set('user_1', user);
五、高级特性
5.1 Extension Methods(扩展方法)
dart
// 为 BuildContext 添加扩展(Flutter 中非常实用)
extension ContextExtension on BuildContext {
ThemeData get theme => Theme.of(this);
ColorScheme get colorScheme => Theme.of(this).colorScheme;
TextTheme get textTheme => Theme.of(this).textTheme;
double get screenWidth => MediaQuery.of(this).size.width;
double get screenHeight => MediaQuery.of(this).size.height;
void showSnackBar(String message) {
ScaffoldMessenger.of(this).showSnackBar(
SnackBar(content: Text(message)),
);
}
}
// 使用
Widget build(BuildContext context) {
return Text(
'Hello',
style: TextStyle(color: context.colorScheme.primary),
);
}
5.2 Cascade Notation(级联操作符 ..)
dart
// 传统写法
final paint = Paint();
paint.color = Colors.blue;
paint.strokeWidth = 2.0;
paint.style = PaintingStyle.stroke;
// 级联写法(更简洁)
final paint = Paint()
..color = Colors.blue
..strokeWidth = 2.0
..style = PaintingStyle.stroke;
// 结合 List 使用
final list = <String>[]
..add('Flutter')
..add('Dart')
..addAll(['iOS', 'Android'])
..sort();
5.3 Factory 构造函数
dart
// 单例模式
class AppConfig {
static AppConfig? _instance;
final String baseUrl;
final String apiKey;
AppConfig._internal({required this.baseUrl, required this.apiKey});
factory AppConfig({required String baseUrl, required String apiKey}) {
_instance ??= AppConfig._internal(baseUrl: baseUrl, apiKey: apiKey);
return _instance!;
}
}
// JSON 反序列化
class User {
final int id;
final String name;
User({required this.id, required this.name});
factory User.fromJson(Map<String, dynamic> json) {
return User(
id: json['id'] as int,
name: json['name'] as String,
);
}
Map<String, dynamic> toJson() => {'id': id, 'name': name};
}
// 类型分发(返回不同子类)
abstract class Shape {
factory Shape.fromType(String type) {
return switch (type) {
'circle' => Circle(),
'square' => Square(),
_ => throw ArgumentError('Unknown shape: $type'),
};
}
}
5.4 Records(Dart 3.0 新特性)
dart
// Record 类型,轻量级数据聚合
(String, int) getInfo() => ('Flutter', 3);
final (name, version) = getInfo(); // 解构
// 命名字段
({String name, int age}) getUser() => (name: 'Alice', age: 25);
final user = getUser();
print(user.name); // Alice
5.5 Pattern Matching(Dart 3.0 模式匹配)
dart
// switch 表达式
String classify(Object obj) => switch (obj) {
int n when n < 0 => 'negative',
int n when n == 0 => 'zero',
int _ => 'positive',
String s => 'string: $s',
_ => 'unknown',
};
// 解构匹配
void processShape(Shape shape) {
switch (shape) {
case Circle(radius: var r):
print('Circle with radius $r');
case Rectangle(width: var w, height: var h):
print('Rectangle ${w}x$h');
}
}
小结
| 特性 | 核心要点 |
|---|---|
| 空安全 | ? 可空类型,! 断言,?? 合并,late 延迟初始化 |
| Future | 单次异步操作,async/await + try-catch |
| Stream | 持续异步数据流,listen + cancel |
| mixin | 多重代码复用,不依赖继承层次 |
| extension | 为已有类添加方法,无需修改原类 |
级联 .. |
链式调用,提升代码可读性 |
| factory | 控制实例创建,单例/JSON 解析/类型分发 |
| 泛型 | 类型安全的通用代码,支持约束 |
👉 下一章:二、UI 组件与布局系统