Flutter 零基础入门(十三):late 关键字与延迟初始化
文章目录
- [Flutter 零基础入门(十三):late 关键字与延迟初始化](#Flutter 零基础入门(十三):late 关键字与延迟初始化)
-
- [一、late 解决的到底是什么问题?](#一、late 解决的到底是什么问题?)
- [二、什么是 late?](#二、什么是 late?)
- [三、最基本的 late 用法](#三、最基本的 late 用法)
- [四、late 与可空类型的区别](#四、late 与可空类型的区别)
-
- [1️⃣ 可空类型(?)](#1️⃣ 可空类型(?))
- [2️⃣ late(非空但延迟)](#2️⃣ late(非空但延迟))
- [五、late 在类中的典型用法](#五、late 在类中的典型用法)
- [六、late final:最常见组合](#六、late final:最常见组合)
- [七、late 的运行时风险(非常重要)](#七、late 的运行时风险(非常重要))
- [八、什么时候应该用 late?](#八、什么时候应该用 late?)
- [九、不该使用 late 的情况](#九、不该使用 late 的情况)
- [十、late vs ? 对比总结](#十、late vs ? 对比总结)
- 十一、一个完整综合示例
- [十二、late 在 Flutter 中的位置](#十二、late 在 Flutter 中的位置)
- 十三、这一篇你真正掌握了什么?
- 十四、总结
- [🔜 下一篇预告](#🔜 下一篇预告)
在前面的学习中,我们已经掌握了:
- 空安全(null safety)
- 可空类型
? - 非空断言
! - enum 状态建模
但你在阅读 Flutter 代码或示例时,一定见过这种写法:
dart
late String title;
或者:
late final User user;
这一篇,我们就来彻底讲清楚:
👉 late 是什么?为什么要用?什么时候用?
一、late 解决的到底是什么问题?
先来看一个问题场景。
class Page {
String title;
Page() {
title = '首页';
}
}
❌ 这段代码在空安全下是不允许的。
为什么?
因为:
title是非空类型- Dart 要求:构造函数结束前必须初始化
但你又确实希望:
- 在构造函数里再赋值
- 而不是在声明时就给初始值
👉 这就是 late 要解决的问题。
二、什么是 late?
late 的含义是:
"这个变量现在不初始化,但我保证稍后一定会初始化"
你是在对编译器做一个承诺。
三、最基本的 late 用法
late String title;
void main() {
title = 'Hello';
print(title);
}
特点:
- 声明时不需要初始值
- 使用前必须赋值
- 否则运行时报错
四、late 与可空类型的区别
1️⃣ 可空类型(?)
String? name;
- 可以一直是 null
- 使用时要判空
2️⃣ late(非空但延迟)
late String name;
- 一定不是 null
- 只是"晚一点初始化"
📌 本质区别:
? 是"可能没有值"
late 是"一定会有值,但现在还没有"
五、late 在类中的典型用法
class User {
late String name;
User(String n) {
name = n;
}
}
这样写的好处:
- 属性非空
- 构造时初始化
- 不需要
?
六、late final:最常见组合
late final String token;
含义是:
- 延迟初始化
- 但只能赋值一次
示例:
class Auth {
late final String token;
void login() {
token = 'abc123';
}
}
📌 这是 Flutter 中极其常见的写法。
七、late 的运行时风险(非常重要)
如果你使用了 late,但忘了赋值就访问:
late String name;
void main() {
print(name); // ❌ 运行时异常
}
注意:
- 编译不会报错
- 运行时直接崩溃
📌 所以 late 是一种责任型关键字。
八、什么时候应该用 late?
你可以在以下情况考虑使用:
✅ 变量一定会有值
✅ 但无法在声明时确定
✅ 且使用前一定会赋值
典型场景:
- 构造函数中初始化
- init 方法中初始化
- 依赖外部数据
九、不该使用 late 的情况
❌ 数据真的可能不存在
❌ 需要频繁判空
❌ 初始化时机不确定
这些情况:
👉 用 ? 更安全
十、late vs ? 对比总结
| 场景 | 推荐 |
|---|---|
| 可能为空 | ? |
| 一定有值,但晚点给 | late |
| 只赋值一次 | late final |
| 不确定是否会赋值 | 不用 late |
十一、一个完整综合示例
class Profile {
late final String userId;
late String name;
Profile(String id) {
userId = id;
name = 'Guest';
}
}
这里:
- userId:延迟 + 不可变
- name:延迟 + 可修改
十二、late 在 Flutter 中的位置
在 Flutter 中,late 常用于:
State类中的变量- 控制器(Controller)
- 依赖注入
- 生命周期初始化
你现在看到的很多 Flutter 示例代码,已经完全能看懂 为什么要用 late 了。
十三、这一篇你真正掌握了什么?
- late 的真正含义
- late 与 null safety 的关系
- late vs ?
- late final 的真实用途
你已经完成了 Dart 变量系统的完整闭环。
十四、总结
这一篇之后,你对 Dart 中:
- 非空
- 可空
- 延迟
- 不可变
已经形成了清晰的判断标准。
你写的代码会越来越像:
"有设计意识的工程代码"
🔜 下一篇预告
《Flutter 零基础入门(十四):Dart 抽象类(abstract)与接口思想》
下一篇我们将学习:
- 什么是抽象类
- abstract 解决什么问题
- 如何用抽象类约束行为
- Flutter 中"万物皆 Widget"的思想基础
从这一篇开始:
你将真正进入 Flutter 架构思维