Swift Tips 014 - Referring to enum cases with associated values as closures

224 阅读2分钟

代码截图

代码出处: Swift Tips 014 by John Sundell

小笔记

这段代码在说什么

代码最开始定义一个名为 UnboxPath 的枚举类型,它有两个枚举值,一个成员值的名称叫做 key,具有 String 类型的关联值,另一个成员值的名称是 keyPath,具有 String 类型的关联值。

紧接着,代码里定义了一个名为 UserSchema 的结构体,它有三个存储属性,类型全部为 UnboxPath 并且设有默认值。

不过最有意思的,也是最特别的地方,则是这三个属性的默认值生成方式,它们是通过一个名为 key 的闭包完成的。

为什么能这么做

为什么 UserSchema 里的 UnboxPath 属性能通过 key 闭包实现呢,我们不妨看一下 key 闭包的定义:

![IMAGE](quiver-image-url/DE61D143B057573E0C5DD72E30B377A1.jpg =526x147)

我们发现 UnboxPath.key 这个枚举关联值变成了一个待执行的闭包,它的入参是 String 类型的实例,而返回值是 UnboxPath 类型的实例,

从某种角度来看,key 闭包此时就像是一种 UnboxPath 的“构造器”,不过这种构造器只能生成名称为 key 的枚举值。

就像代码截图里的标题所说一样,这里我们将枚举关联值当做闭包来使用,所以到这里,你的疑惑是不是得到了解答呢?

这样做的好处

将关联值当做闭包来使用的好处,目前能想到的好处主要有以下几点:

  1. 简化代码,提升阅读体验
  2. 提供了一种生成特定枚举值的方法,方便使用
  3. 在迁移 Enum 类型时,能减少工作量

前面两点不用多说,估计大家很容易能想到它的实际场景。

至于最后一点,我们不妨假设因为一些原因需要将 UnboxPath 升级为 NewUnboxPath 时,使用这种关联值的写法,能够帮我们避免一个个替换 nameageposts 的类型,这时它与 typealias 起到的作用很相似。

enum UnboxPath {
    case key(String)
    case keyPath(String)
}

enum NewUnboxPath {
    case key(String)
    case keyPath(String)
}

struct UserSchema {
    static let name = key("name")
    static let age = key("age")
    static let posts = key("posts")
    
    // 只需要删除下面注释的代码
    //private static let key = UnboxPath.key
    // 将 key 的类型转换为 NewUnboxPath.key
    private static let key = NewUnboxPath.key
}