Skip to content

速查 02 · Dart ​

按问题索引。Ctrl+F 页内搜索。 系统学习见 01 篇 Dart 语言基础、06 篇 异步与进阶语法。

目录 ​


变量与空安全 ​

dart
final name = 'Tom';                 // 运行时确定,只能赋值一次(推荐默认用 final)
const pi = 3.14;                    // 编译期常量
var count = 0;                      // 可变(尽量少用)
late final Data data;               // 延迟初始化(声明时不赋值,使用前必须赋值)

String? maybeNull;                  // 可空类型

// 空安全三剑客
maybeNull?.length                   // 为 null 时整体返回 null,不报错
maybeNull ?? 'default'              // 为 null 时取默认值
maybeNull!                          // 强制解包(为 null 就崩,慎用)
maybeNull ??= 'init';               // 为 null 时赋值

// 条件赋值 / 判空后调用
if (maybeNull case final v?) { use(v); }   // 模式匹配(Dart 3)
final len = maybeNull?.length ?? 0;

实践原则:能用 final 就不用 var;能不用 ! 就不用——! 是运行时崩溃的主要来源。


字符串 ​

dart
// 插值
'Hello $name'                       // 简单变量
'Total: ${a + b}'                   // 表达式

// 多行
'''line1
line2'''

// 原始字符串(不转义,写正则/路径很方便)
r'\d+\.\d+'

// 常用操作
str.split(',')                      // 分割
str.trim()                          // 去首尾空格
str.contains('abc')                 // 包含
str.startsWith('a')                 // 前缀
str.replaceAll('a', 'b')            // 替换
str.substring(0, 3)                 // 截取
str.padLeft(2, '0')                 // 补零 → "07"
str.toLowerCase() / str.toUpperCase()

// 拼接用 + 或相邻字符串字面量
'abc' 'def'                         // → 'abcdef'(自动连接)

集合操作 ​

dart
final list = <String>['a', 'b', 'c'];
final map = <String, int>{'a': 1};
final set = <String>{'a', 'b'};

// List 高频
list.map((e) => e.toUpperCase()).toList()       // 转换
list.where((e) => e.length > 1).toList()        // 过滤
list.firstWhere((e) => e == 'a', orElse: () => '')
list.expand((e) => [e, e]).toList()             // 展开
list.any((e) => e.isEmpty)                      // 任一满足
list.every((e) => e.isNotEmpty)                 // 全部满足
list.fold(0, (sum, e) => sum + e.length)        // 归约
list.sort((a, b) => a.compareTo(b))             // 排序
list.reversed.toList()                          // 反转
list.take(3) / list.skip(2)                     // 取前 N / 跳过前 N
list.join(',')                                  // 转字符串
[...list1, ...list2]                            // 展开合并
list.asMap().entries                            // 带索引遍历
list.indexed                                    // Dart 3:(index, element)

// Map 高频
map['key'] ?? 0                                 // 安全取值
map.containsKey('key')
map.putIfAbsent('k', () => 1)
map.entries.map((e) => '${e.key}=${e.value}')
{...map1, ...map2}                              // 合并(后者覆盖)

// 集合内的 if / for(Dart 特色,写 UI 极方便)
Column(children: [
  const Header(),
  if (isLoading) const Loading(),               // 条件
  for (final item in items) Tile(item),         // 循环
])

类与构造 ​

dart
class User {
  final String name;
  final int age;
  const User({required this.name, this.age = 0});   // 命名参数 + 默认值

  // 命名构造
  User.guest() : name = 'guest', age = 0;

  // 工厂构造(可返回缓存/子类)
  factory User.fromJson(Map<String, dynamic> j) =>
      User(name: j['name'], age: j['age'] ?? 0);

  // getter
  bool get isAdult => age >= 18;

  // 拷贝
  User copyWith({String? name}) => User(name: name ?? this.name, age: age);

  @override
  String toString() => 'User($name, $age)';
}

// 级联(链式配置,省临时变量)
final user = User(name: 'Tom')..age = 18;
final sb = StringBuffer()..write('a')..write('b');

// 继承 / 混入 / 实现 的顺序
class A extends B with C implements D {}

本项目用 Freezed 生成 copyWith/==/fromJson,手写仅限简单类,见 01 篇。


函数与语法糖 ​

dart
// 箭头函数(单行)
int add(int a, int b) => a + b;

// 命名参数 vs 位置参数
void f({required String a, int b = 1}) {}       // 命名(调用 f(a: 'x'))
void g(String a, [int b = 1]) {}                // 可选位置(调用 g('x', 2))

// 级联 / 空安全级联
obj..a = 1..b = 2;
obj?..a = 1;                                     // obj 为 null 则整体跳过

// 展开运算符
final args = <String>['a', ...moreArgs];

// 模式匹配(Dart 3)
switch (obj) {
  case [int a, int b] when a > b: ...            // 解构 List + 守卫
  case {'name': String n}: print(n);             // 解构 Map
  case User(:final name): print(name);           // 解构对象
  default: ...
}
if (json case {'code': 0, 'data': final d}) { use(d); }   // if-case

// Records(Dart 3,多返回值)
(int, String) f() => (1, 'a');
final (n, s) = f();                              // 解构

异步 ​

dart
// async/await
Future<Data> load() async {
  final r = await api.fetch();
  return r;
}

// 并发(同时发起,总耗时取最慢)
final results = await Future.wait([api.a(), api.b()]);
final (a, b) = await (api.a(), api.b()).wait;     // Dart 3 Records 写法

// 错误处理
try { await api.fetch(); } catch (e, s) { log(e, s); } finally { ... }
final r = await api.fetch().catchError((e) => fallback);

// 超时 / 延迟
await Future.delayed(const Duration(milliseconds: 300));
await api.fetch().timeout(const Duration(seconds: 10));

// Stream
stream.listen((v) {}, onError: (e) {}, onDone: () {});
await for (final v in stream) { print(v); }
stream.map((e) => e * 2).where((e) => e > 1)
streamController.add(v); await streamController.close();   // 记得关闭

// 只执行一次(缓存结果)
late final _cached = api.fetch();                // 天然单例异步

// 不阻塞 UI 的重计算 → Isolate
final r = await Isolate.run(() => heavyCompute());

事件循环/微任务原理见 06 篇。


类型与转换 ​

dart
int.parse('42')
double.parse('3.14')
num.tryParse('abc')                 // 失败返回 null(推荐,不抛异常)
42.toString()
3.14159.toStringAsFixed(2)          // "3.14"
(3.7).round() / .floor() / .ceil()

// 类型判断与转换
if (x is String) { x.length; }      // is 后自动提升类型
x as String                         // 强制转换(失败抛异常)
x is! String                        // 否定

// JSON
import 'dart:convert';
jsonEncode(obj)                     // 对象 → 字符串
jsonDecode(str)                     // 字符串 → Map/List
jsonDecode(str) as Map<String, dynamic>

// 时间
DateTime.now()
DateTime.parse('2026-09-03')
d.add(const Duration(days: 1))
d.difference(other).inDays
DateFormat('yyyy-MM-dd').format(d)  // intl 包

常用模式 ​

dart
// 单例
class Repo { Repo._(); static final instance = Repo._(); }

// 枚举带值(Dart 2.17+)
enum Status { loading, ok('成功'), err('失败');
  const Status([this.label]); final String? label; }

// extension(给现有类型加方法)
extension StringX on String {
  bool get isPhone => RegExp(r'^1\d{10}$').hasMatch(this);
}

// sealed class(Dart 3,配合 switch 穷尽检查)
sealed class Result {}
class Ok extends Result {}
class Err extends Result {}

// typedef(简化长类型)
typedef JsonMap = Map<String, dynamic>;

// 断言与调试
assert(cond, 'message');            // 仅 debug 生效
debugPrint('log');                  // 长日志不截断(本项目用 AppLogger)

相关:Flutter 速查 | 返回速查区