Вложенные перечисления, допускающие кратные сроки - PullRequest
0 голосов
/ 02 марта 2019

Я надеюсь достичь определенного стиля синтаксиса / функциональности enum, однако я не уверен, как этого добиться.В настоящее время у меня есть следующее:

internal enum Timeframe: Equatable {

    // MARK: - Cases

    case hour(count: Int)
    case day(count: Int)
    case week(count: Int)
    case month(count: Int)
    case year(count: Int)
    case all
    case exact(date: Date)
    case unspecified
}

Я хотел бы исключить значение, связанное с подсчетом, если это не требуется.Например:

let oneDayTimeframe: Timeframe = .day
let twoDayTimeframe: Timeframe = .day.multiplied(by: 2)

Возможно ли это?Даже если нет способа достичь именно того, что я ищу, я был бы признателен за предложения о потенциальных улучшениях.В большинстве случаев я использую (count: 1), что кажется довольно многословным.Если бы значения по умолчанию были доступны со связанными значениями, я бы использовал

case hour(count: Int = 1)

Любые предложения?

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

Немного повторяясь с ответом, который вы предоставили:

enum TimeFrame: Equatable {

    case all
    case countable(timeFrame: CountableTimeFrame)
    case exact(date: Date)
}

enum CountableTimeFrame: Equatable {

    case hour
    case day
    case week
    case month
    case year

    indirect case multiple(CountableTimeFrame, Int)

    var timeFrame: TimeFrame {
        return .countable(timeFrame: self)
    }

    static func * (left: CountableTimeFrame, right: Int) -> CountableTimeFrame {
        switch left {
        case .multiple(let timeFrame, let count):
            return .multiple(timeFrame, count * right)
        default:
            return .multiple(left, right)
        }
    }

    static func * (left: Int, right: CountableTimeFrame) -> CountableTimeFrame {
        return right * left
    }
}

Запретит неправильное использование, например, disallow:

let timeFrame: TimeFrame = .multiple(.exact(date: someDate), 666)
let timeFrame: TimeFrame = .multiple(unspecified, 40)
let timeFrame: TimeFrame = .multiple(all, -1) 

И разрешит умножение с помощью оператора *, например,

let timeFrame: CountableTimeFrame = 4 * .hour
print(timeFrame) // multiple(__lldb_expr_5.CountableTimeFrame.hour, 4)
print(timeFrame * 2) // multiple(__lldb_expr_5.CountableTimeFrame.hour, 8)

А. Не указано:

let optionalTimeFrame: TimeFrame? = nil
0 голосов
/ 02 марта 2019

Я обнаружил, что это возможно при использовании рекурсивных перечислений.Хотя это не совсем то, что я предложил, это дает аналогичный результат:

internal enum Timeframe: Equatable {

    // MARK: - Cases

    case hour
    case day
    case week
    case month
    case year
    case all
    case exact(date: Date)
    case unspecified

    // MARK: - Indirect Cases

    indirect case multiple(Timeframe, Int)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...