Как проверить вложенные перечисления Swift только на равенство внешних перечислений? - PullRequest
0 голосов
/ 29 мая 2018

Я пытаюсь использовать вложенные перечисления для описания моей модели таким образом, что делает недопустимые состояния невозможными и обеспечивает категоризацию на верхнем уровне.Прямо сейчас мой (упрощенный) код:

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 ]

0 голосов
/ 29 мая 2018

В зависимости от вашего варианта использования вы можете преобразовать 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)
0 голосов
/ 29 мая 2018

Я думаю, что вам нужен оператор 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, если вы проверили все возможные комбинации).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...