OrOther 是一个宏,它可以向任何枚举添加一个“空白”的 .other(_:) case。 你只需要创建一个空的枚举,添加一个 private 的嵌套枚举,命名为 Options,并指定一个显式的原始值类型,添加你想要的显式 case,然后将 @OrOther 附加到主枚举上。
OrOther 将自动合成你添加到 Options 的所有枚举 case,然后添加一个额外的 .other(_:) case。 .other(_:) case 具有与 Options 枚举的原始值类型相同的关联值。
它还会自动合成附加枚举对 RawRepresentable 的一致性,通过添加一个合成的计算属性 rawValue 和 init(rawValue:) 初始化器
rawValue 返回嵌套 Options 枚举中匹配 case 的 rawValue,除非它是 .other,在这种情况下,将返回关联的值。init(rawValue:) 是 *非失败* 的,因为它首先尝试将 rawValue 与 Options 枚举中的值匹配并返回匹配的 case。 如果在 Options 中没有匹配的 case,它将返回 rawValue 作为 .other case 的关联值。然后,你可以根据需要向主枚举添加其他协议(例如,在下面的示例中将 Codable 添加到 EnumTest)。
此外,由于宏无法为 private 类型添加扩展,因此你无法将主枚举设为 private。 目前唯一的解决方法是显式地让主枚举遵循 RawRepresentable。
@OrOther
enum EnumTest: Codable {
private enum Options: String {
case a
case b
case c, d, e, f
}
}
enum EnumTest {
private enum Options: String { ... }
typealias RawValue = String
case a, b, c, d, e, f, other(String)
var rawValue: RawValue {
switch self {
case .a:
return Options.a.rawValue
case .b:
return Options.b.rawValue
case .c:
return Options.c.rawValue
case .d:
return Options.d.rawValue
case .e:
return Options.e.rawValue
case .f:
return Options.f.rawValue
case .other(let string):
return string
}
}
init(rawValue: RawValue) {
if let this = Options(rawValue: rawValue) {
switch this {
case .a:
self = .a
case .b:
self = .b
case .c:
self = .c
case .d:
self = .d
case .e:
self = .e
case .f:
self = .f
}
} else {
self = .other(rawValue)
}
}
}
以下协议可以显式添加到主枚举,并且 @OrOther 将自动合成其一致性
EquatableHashableEncodable / Decodable / CodableCaseIterable