我有各种枚举,如下所示。
enum PaperOrientation : Int { case portrait, landscape }
enum MetricType : Int { case inches, metric }
我制作了 Int 类型的枚举,这样实例的值就可以用 CoreData 保存为数字。
当从 CoreData 检索值以在程序中使用时,我最终得到非常相似的转换例程,如下所示。
通常,我需要一些默认值——例如,它是程序最新版本的新枚举,而该变量的值实际上可能并未保存在 CoreData 中。例如,为程序的第二个版本添加了 MetricType。检索在 rev 1 中创建的论文不会保存度量值。对于 nil 值,我想使用论文最初假定的默认值。
class ConversionRoutine {
class func orientationFor(_ num: NSNumber?) -> PaperOrientation {
if let iVal = num?.intValue {
if let val = PaperOrientation(rawValue: iVal) {
return val
}
}
return PaperOrientation(rawValue: 0)!
}
class func metricTypeFor(_ num: NSNumber?) -> MetricType {
if let iVal = num?.intValue {
if let val = MetricType(rawValue: iVal) {
return val
}
}
return MetricType(rawValue: 0)!
}
}
有没有办法减少冗余?
我在下面介绍了一种非常有效的方法。但欢迎更多的改进或改进。
最佳答案
下面的 Swift 4 示例使用基于 RawRepresentable 的 Defaultable 协议(protocol)。第一步是创建一个可以在初始化程序失败时使用的默认值。请注意 Defaultable 协议(protocol)不限于 Int 枚举。 String 枚举也可以使用它。
protocol Defaultable : RawRepresentable {
static var defaultValue : Self { get }
}
protocol IntDefaultable : Defaultable where RawValue == Int {
}
extension IntDefaultable {
static func value(for intValue : Int) -> Self {
return Self.init(rawValue: intValue) ?? Self.defaultValue
}
static func value(for num : NSNumber?) -> Self {
if let iVal = num?.intValue {
return self.value(for: iVal)
}
return Self.defaultValue
}
}
定义 Defaultable 协议(protocol)后,我可以创建一个将用于 Int 枚举的 IntDefaultable 协议(protocol)。
在 IntDefaultable 的扩展中,我可以创建通用代码来处理转换。首先,我创建了一个接受 Int 的函数。然后我创建了一个函数,它接受一个 NSNumber 可选。
接下来,看看其中一个枚举是如何构建的:
enum MetricType : Int, Codable, IntDefaultable { case inches, metric
static var defaultValue: MetricType = .inches
}
我还决定声明枚举 Codable,这可能会有用。当我添加 IntDefaultable 协议(protocol)时,添加带有代码完成的 defaultValue 代码行变得相当容易 - 转到新行并键入“def”-tab,然后键入“=。”,然后从弹出窗口。请注意,通常我想选择第一个枚举值,但默认值可以是任何一个。
最后一件事是调用转换例程以从 CoreData 获取值
let units = MetricType.value(for: self.metricType) // where self.metricType is the NSManagedObject member.
关于swift - 如何减少 Swift 枚举转换代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48053868/