嵌套枚举以允许多个时间范围
Nested enums to allow multiples of timeframes
我希望实现某种枚举风格 syntax/functionality,但我不确定如何实现它。目前我有以下内容:
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)
有什么建议吗?
我发现使用递归枚举是可能的。虽然与我建议的不完全相同,但得到了类似的结果:
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)
}
对您提供的答案进行一些迭代:
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
}
}
禁止滥用,例如不允许:
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)
和.unspecified:
let optionalTimeFrame: TimeFrame? = nil
我希望实现某种枚举风格 syntax/functionality,但我不确定如何实现它。目前我有以下内容:
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)
有什么建议吗?
我发现使用递归枚举是可能的。虽然与我建议的不完全相同,但得到了类似的结果:
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)
}
对您提供的答案进行一些迭代:
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
}
}
禁止滥用,例如不允许:
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)
和.unspecified:
let optionalTimeFrame: TimeFrame? = nil