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
将自动合成其一致性
Equatable
Hashable
Encodable
/ Decodable
/ Codable
CaseIterable