【问题标题】:SWIFT - Nested enumsSWIFT - 嵌套枚举
【发布时间】:2020-08-01 22:21:58
【问题描述】:

目前我正在使用枚举,我需要在某些对象存储不同的枚举案例中,但我想避免在每个实现中都使用 switch 语句。在我的自定义对象中,我从枚举“CarModType”中保存了他的类型,其中我将更多子类型指定为“Engine、Interior、Exterior...”。所以我可以在我的对象中存储当前对象的类型为“Interior.Seats”,并且我不需要使用我的“类型”可变性(var type: PostProcessingFramework.CarModType?)来存储不同的枚举CarModType 例如“Engine, Exterior, Interior”。我的枚举看起来像这样:

public enum CarModType {
        case interior(Interior)
        case exterior(Exterior)
        case engine(Engine)
        case driveTrain(DriveTrain)
        case suspension(Suspension)
        case steering(Steering)
        case brakes(Brakes)
        case extra(Extra) 

    enum Interior: String,CaseIterable {
            
            case steering = "interior.steering"
            case seats = "interior.seats"
            case shiftSystem = "interior.shiftSystem"
            case pedals = "interior.pedals"
            case accessories = "interior.accessories"
            case centralUnit = "interior.centralUnit"
            case extra = "interior.extra"
            
            
            class stored {
                static let array:[PostProcessingFramework.CarModType.Interior] = [.accessories,.centralUnit,.extra,.pedals,.seats,.shiftSystem,.steering]
            }

            static func returnTitle(category: PostProcessingFramework.CarModType.Interior) -> String {
                switch category {
                case .steering:
                    return "Steering"
                case .seats:
                    return "Seats"
                case .shiftSystem:
                    return "Shift System"
                case .pedals:
                    return "Pedals"
                case .accessories:
                    return "Accessories"
                case .centralUnit:
                    return "Central Unit"
                case .extra:
                    return "Extra"
                }
            }
        }

然后我遇到了其他问题,由于我的数据库,我将这种类型保存在他的 rawValue 中,正如我在 subTypes 中指定的那样。因此,我想出了一些函数,它们会将所有枚举案例转换为字典,然后我可以通过使用键作为嵌套枚举(子类型)的 rawValue 访问该字典来获得特定的“Type” (例如 CarModType.Engine(.cylinderHead))来自 rawValue。我的职能:

static func returnType(rawValue: String) -> CarModType? {
     let semaphore = DispatchSemaphore(value: 0)
     let dictionaries = [
         Dictionary(uniqueKeysWithValues: CarModType.Interior.allCases.map{ (CarModType.interior($0).stringValue,CarModType.interior($0)) }),
         Dictionary(uniqueKeysWithValues: CarModType.Exterior.allCases.map{ (CarModType.exterior($0).stringValue,CarModType.exterior($0)) }),
         Dictionary(uniqueKeysWithValues: CarModType.Engine.allCases.map{ (CarModType.engine($0).stringValue,CarModType.engine($0)) })
     ]
     var dict = [String:CarModType]()
     var i = 0
     for subDict in dictionaries {
         dict.merge(subDict){(_, curr) in curr }
         i += 1
         if i == dictionaries.count {
             semaphore.signal()
         }
     }
     semaphore.wait()
     if let val = dict[rawValue] {
         return val
     } else {
        return nil
     }
 }

 var stringValue: String {
     switch self {
         
     case let .interior(subtype):
         if let type = PostProcessingFramework.CarModType.Interior.init(rawValue: subtype.rawValue) {
             return type.rawValue
         } else {
             return ""
         }
     case let .exterior(subtype):
         if let type = PostProcessingFramework.CarModType.Exterior.init(rawValue: subtype.rawValue) {
             return type.rawValue
         } else {
             return ""
         }
      case let .engine(subtype):
         if let type = PostProcessingFramework.CarModType.Engine.init(rawValue: subtype.rawValue) {
             return type.rawValue
         } else {
             return ""
         }
    }
}

难道没有更好、更“优雅”的方式来做到这一点吗?非常感谢您的回答!

【问题讨论】:

    标签: ios swift enums


    【解决方案1】:

    假设所有原始值都是唯一的,就像 Interior 使用类似字符串的命名空间一样,您可以在顶层添加一个 init 并尝试创建每个子类型的实例,直到成功了

    这里是前两个 case 元素的示例

    init?(asRaw: String) {
        if let item = Interior(rawValue: asRaw) {
            self = CarModType.interior(item)
        } else if let item = Exterior(rawValue: asRaw) {
            self = CarModType.exterior(item)
        //... rest of case items here
        } else {
            return nil
        }
    }
    

    【讨论】:

    • 谢谢。有什么办法可以避免 long if let 阻塞? (如果有大量子类型?例如:20)
    • @MaheshDeSilva 很难说没有更多信息,但您必须以某种方式将每个可能的值与类型匹配。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多