我有各种各样的枚举,例如下面的内容。
enum PaperOrientation : Int { case portrait, landscape }
enum MetricType : Int { case inches, metric }
我创建了Int类型的枚举,以便可以使用CoreData将实例的值保存为数字。
从CoreData中检索要在程序中使用的值时,我最终会得到非常相似的转换例程,如下所示。
通常,我想要一些默认值 - 例如,对于最新版本的程序,它是新枚举的情况,并且该变量的值实际上可能实际上没有保存在CoreData中。例如,为程序的第二次转换添加了MetricType。检索在rev 1中创建的纸张将不会保存度量值。对于零值,我想使用最初假定纸张的默认值。
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)!
}
}
有没有办法减少冗余?
我提出了一个非常好的方法。但欢迎更多改进或改进。
答案 0 :(得分:3)
下面的Swift 4示例使用基于RawRepresentable的Defaultable协议。第一步是创建一个defaultValue,可以在初始化程序失败时使用。请注意,Defaultable协议不限于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协议之后,我可以创建一个IntDefaultable协议,用于Int枚举。
在IntDefaultable的扩展中,我可以创建通用代码来处理转换。首先,我创建一个带Int的函数。然后我创建一个NSNumber可选的函数。
接下来,看看如何构建其中一个枚举:
enum MetricType : Int, Codable, IntDefaultable { case inches, metric
static var defaultValue: MetricType = .inches
}
我还决定声明枚举Codable,这可能很有用。当我添加IntDefaultable协议时,使用代码完成添加defaultValue代码行变得相当容易 - 转到新行并键入“def”-tab,然后键入“=。”,然后从中选择一个值弹出。请注意,我经常要选择第一个枚举值,但默认值可以是任何一个。
最后一件事就是调用转换例程来获取CoreData的值
let units = MetricType.value(for: self.metricType) // where self.metricType is the NSManagedObject member.
答案 1 :(得分:1)
您可以在enum
中添加初始值设定项。
enum PaperOrientation : Int {
case portrait, landscape
init(number: NSNumber) {
self = PaperOrientation(rawValue: number.intValue) ?? .portrait
}
}