代码之家  ›  专栏  ›  技术社区  ›  Chris

如何仅检查swift嵌套枚举是否与外部枚举相等?

  •  1
  • Chris  · 技术社区  · 6 年前

    我试图用嵌套的枚举来描述我的模型,这样就不可能出现非法状态,并在顶层提供分类。现在,我的(简化)代码是:

    enum SportsEvent {
    
        enum RunningEvent {
            case sprint
            case marathon
        }
    
        enum ThrowingEvent {
            case hammer
            case javelin
            case discus
        }
    
        case running(event: RunningEvent)
        case throwing(event: ThrowingEvent)
    
        func isSameCategory(as other: SportsEvent) -> Bool {
    
            return false
        }
    }
    
    let sprint = SportsEvent.running(event: .sprint)
    let javelin = SportsEvent.throwing(event: .javelin)
    let hammer = SportsEvent.throwing(event: .hammer)
    
    sprint.isSameCategory(as: javelin)      // False
    hammer.isSameCategory(as: javelin)      // True
    

    感觉应该是琐碎的 if case ... 一个通配符,但我不知道如何实现。我希望不需要一个巨大的开关声明,因为我的实际模型更复杂。

    2 回复  |  直到 6 年前
        1
  •  3
  •   Martin R    6 年前

    我认为您需要一个switch语句,其中有一个复合大小写列出所有 外部枚举的可能相同值组合, 加上默认情况:

    func isSameCategory(as other: SportsEvent) -> Bool {
        switch (self, other) {
        case (.running, .running),
             (.throwing, .throwing):
            return true
        default:
            return false
        }
    }
    

    或(归属于@hamish):

    func isSameCategory(as other: SportsEvent) -> Bool {
        switch (self, other) {
        case (.running, .running),
             (.throwing, .throwing):
            return true
        case (.running, _),
             (.throwing, _):
            return false
        }
    }
    

    它的优点是编译器可以检查所有的情况。对于具有 n 使 2 * n switch语句中的事例(这比 n * n 如果你检查了所有可能的组合)。

        2
  •  0
  •   Sulthan    6 年前

    根据您的用例,您可能能够转换 SportEvent 协议:

    enum RunningEvent {
        case sprint
        case marathon
    }
    
    enum ThrowingEvent {
        case hammer
        case javelin
        case discus
    }
    
    enum SportEventCategory {
        case running
        case throwing
    }
    
    protocol SportEvent {
        var category: SportEventCategory { get }
    }
    
    extension RunningEvent: SportEvent {
        var category: SportEventCategory {
            return .running
        }
    }
    
    extension ThrowingEvent: SportEvent {
        var category: SportEventCategory {
            return .throwing
        }
    }
    
    let sportEvent1: SportEvent = RunningEvent.sprint
    let sportEvent2: SportEvent = ThrowingEvent.hammer
    print(sportEvent1.category == sportEvent2.category)
    

    甚至作为一个平面枚举:

    enum SportEvent {
        enum Category {
            case running
            case throwing
        }
    
        case sprint
        case marathon
        case hammer
        case javelin
        case discus
    
        var category: Category {
            switch self {
            case .sprint, .marathon, .hammer:
                return .running
            case .javelin, .discus:
                return .throwing
            }
        }
    }
    
    let sportEvent1: SportEvent = .sprint
    let sportEvent2: SportEvent = .marathon
    print(sportEvent1.category == sportEvent2.category)