LESSON 09 / 577 分钟

enum、protocol、extension 与泛型

这些能力让状态更清楚、依赖更可替换,而不需要复杂继承树。

用你的前端经验理解

protocol 与 TS interface 有相似用途,但包含更严格的遵循规则;带关联值 enum 很适合替代多个互相矛盾的布尔变量。

为什么需要它

enum 适合表达有限且互斥的业务状态,protocol 描述一种能力,泛型让算法在保留类型信息的同时复用。它们解决不同问题。例如加载页面不应该同时 isLoading=true、hasError=true、hasData=true;用一个带关联值的 enum,可以让不合理的组合更难被构造出来。

它是怎样工作的

协议描述调用者需要什么,不要求对象属于某个继承树。真实网络仓库与测试仓库都可以满足同一协议。extension 可以补充方法或协议遵循,但不能凭空给已有类型添加普通存储属性。泛型中的约束决定能对参数做哪些操作;看到 some 与 any 时应意识到前者隐藏但保留具体类型,后者表达可容纳符合协议的值。

把关键概念连起来

1

enum

用 loading、success(data)、failure(error) 表达互斥状态;switch 让遗漏的状态更容易暴露。

2

protocol + extension

定义行为约定,并扩展类型的能力。可用于注入网络服务的真实实现与测试替身。

3

泛型

保留具体类型关系、复用算法。some Protocol 隐藏某个确定类型,any Protocol 表示可容纳遵循协议的值,两者不等价。

Swift · 示例片段
enum LoadState {    case idle    case loading    case loaded([String])    case failed(String)}

用于理解当前概念的代码片段;部分示例需要放入对应工程与作用域,并补齐上下文。

把页面状态改为明确的分支

  1. 定义 idle、loading、loaded([String]) 和 failed(String)。数据和错误只存在于需要它们的状态里。
  2. 界面通过 switch 决定显示按钮、进度、列表或重试。编译器要求覆盖所有枚举情况,有助于避免新增状态遗漏页面。
  3. 再为加载服务定义协议,让预览注入立即成功、空结果和失败实现,而无需真正发请求。

这里需要你亲自判断

不要为了“架构高级”给每个 struct 都配一个 protocol;只有确实存在替换需求时才抽象。

做一个小练习

把 isLoading、hasError、hasData 三个 Bool 改成一个加载状态 enum。

  1. 用 enum 表达未登录、登录中、已登录用户和登录失败。
  2. 说明“已登录但没有用户对象”如何通过关联值模型被避免。
展开参考思路与验收标准

已登录状态应携带所需用户数据,而不是额外维护一个可能为 nil 的全局 user。协议只暴露页面需要的加载能力,不应为了可测试性复制真实服务的全部内部方法。

为什么使用加载状态 enum?

继续查阅官方资料
Swift 官方文档

本课聚焦核心认知。具体 API、系统要求与发布政策,以当前官方文档和工程验证为准。

答对理解题后即可标记完成