使用枚举建模状态机
使用 Swift 枚举安全地表示应用状态转换。
第 4 / 4 课12 个步骤
使用枚举建模状态机 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。
欢迎
枚举非常适合建模有限状态机。每种情况都是一个状态;转换则是返回下一个状态的函数。这种方法可以让非法状态无法表示。
简单状态枚举
```swift
enum TrafficLight {
case red, yellow, green
func next() -> TrafficLight {
switch self {
case .red: return .green
case .green: return .yellow
case .yellow: return .red
}
}
}
var light = TrafficLight.red
light = light.next() // .green
```
带关联数据的状态
```swift
enum LoadState {
case idle
case loading(progress: Double)
case loaded(T)
case failed(Error)
}
var state: LoadState<[String]> = .idle
state = .loading(progress: 0.5)
state = .loaded(["alice","bob"])
```
转换函数
```swift
func transition(_ state: LoadState, event: AppEvent) -> LoadState {
switch (state, event) {
case (.idle, .startFetch): return .loading(progress: 0)
case (.loading, .progress(let p)): return .loading(progress: p)
case (.loading, .success(let d)): return .loaded(d)
case (.loading, .error(let e)): return .failed(e)
default: return state
}
}
```
为什么使用枚举状态机?
优点:
• 完备的 switch——编译器会强制您处理所有状态
• 不可能出现非法组合(例如没有数据的 `loaded`)
• 状态是一种值——易于测试、复制和记录
• UI 可以根据状态执行 switch 并进行相应渲染
根据状态渲染 UI
```swift
func render(_ state: LoadState<[User]>) {
switch state {
case .idle: showEmptyView()
case .loading(let p): showProgress(p)
case .loaded(let users): showList(users)
case .failed(let err): showError(err)
}
}
```
播放器状态机
```swift
enum PlayerState {
case stopped
case playing(track: String, position: TimeInterval)
case paused(track: String, position: TimeInterval)
}
```
只有 `playing` 和 `paused` 携带音轨信息,`stopped` 不携带,因此模型本身就能清楚地说明含义。
防止无效转换
```swift
extension PlayerState {
mutating func play(track: String) {
guard case .stopped = self else { return }
self = .playing(track: track, position: 0)
}
mutating func pause() {
if case .playing(let t, let p) = self {
self = .paused(track: t, position: p)
}
}
}
```
测试状态机
```swift
func testLight() {
var l = TrafficLight.red
assert(l.next() == .green)
assert(l.next().next() == .yellow)
}
```
具有纯转换函数的状态机可以轻松进行单元测试,不需要模拟对象。
组合状态机
大型应用通常会有多个状态机协同工作:
```swift
struct AppState {
var auth: AuthState
var data: LoadState<[Article]>
var ui: UIState
}
```
在 Flux/Redux 风格的架构中,可以将它们组合到单个根状态结构中。
快速检查
是什么让枚举状态机具备编译安全性?
回顾
要点总结:
• 每种情况就是一个状态;转换就是返回下一个状态的函数
• 关联值携带特定于状态的数据
• 完备的 switch = 由编译器强制处理所有状态
• 纯转换函数易于进行单元测试
• 可以在根状态结构中组合多个状态机
课程完成!下一节:协议组合。
免费开始
用 AI 导师学习 Swift — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 122
- 课程
- 409
常见问题解答
「使用枚举建模状态机」课时是免费的吗?
是的 — 「使用枚举建模状态机」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。
「使用枚举建模状态机」这节课中我会学到什么?
使用 Swift 枚举安全地表示应用状态转换。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Swift Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「使用枚举建模状态机」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Swift Academy 课中编写并运行代码吗?
能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 原始值与 CaseIterable
- 用于丰富数据的关联值
- 间接枚举与递归结构
- 使用枚举建模状态机