使用比较运算符扩展 Int 枚举
Extend Int enum with comparison operators
你经常有这样的 Int 枚举:
enum Difficulty: Int {
case Easy = 0
case Normal
case Hard
}
Difficulty
值有一定的意义,我们可能想为它们引入顺序。比如某处我们需要比较:
let isBonusAvailable = level.difficulty.rawVAlue <= Difficulty.Hard.rawValue
我想让这段代码短一点:
let isBonusAvailable = level.difficulty <= .Hard
直接在Difficulty
后面加上<=
,可以轻松实现。但是我想从总体上解决这个问题,所以我尝试了这种超级棘手的方法:
protocol RawRepresentableByInt {
var rawValue: Int { get }
}
extension RawRepresentableByInt {
static func <(lhs: RawRepresentableByInt, rhs: RawRepresentableByInt) -> Bool {
return lhs.rawValue < rhs.rawValue
}
static func >(lhs: RawRepresentableByInt, rhs: RawRepresentableByInt) -> Bool {
return lhs.rawValue > rhs.rawValue
}
static func <=(lhs: RawRepresentableByInt, rhs: RawRepresentableByInt) -> Bool {
return lhs.rawValue <= rhs.rawValue
}
static func >=(lhs: RawRepresentableByInt, rhs: RawRepresentableByInt) -> Bool {
return lhs.rawValue >= rhs.rawValue
}
}
// Error: Extension of protocol 'RawRepresentable' cannot have an inheritance clause
extension RawRepresentable: RawRepresentableByInt where RawValue == Int {
}
它产生一个编译器错误:
Error: Extension of protocol 'RawRepresentable' cannot have an inheritance clause
我觉得在逻辑上和Int
enum
相比,没有什么是无法实现的。请帮我欺骗 Swift 编译器。任何也需要此类扩展的人都可以参加。
这比我想象的要容易。所以,基本上你可以使用 Self
而不是创建一个额外的协议。
enum Difficulty: Int {
case Easy = 0
case Normal
case Hard
}
extension RawRepresentable where RawValue: Comparable {
static func <(lhs: Self, rhs: Self) -> Bool {
return lhs.rawValue < rhs.rawValue
}
static func >(lhs: Self, rhs: Self) -> Bool {
return lhs.rawValue > rhs.rawValue
}
static func <=(lhs: Self, rhs: Self) -> Bool {
return lhs.rawValue <= rhs.rawValue
}
static func >=(lhs: Self, rhs: Self) -> Bool {
return lhs.rawValue >= rhs.rawValue
}
}
let easy = Difficulty.Easy
print(easy > .Hard) // false
你经常有这样的 Int 枚举:
enum Difficulty: Int {
case Easy = 0
case Normal
case Hard
}
Difficulty
值有一定的意义,我们可能想为它们引入顺序。比如某处我们需要比较:
let isBonusAvailable = level.difficulty.rawVAlue <= Difficulty.Hard.rawValue
我想让这段代码短一点:
let isBonusAvailable = level.difficulty <= .Hard
直接在Difficulty
后面加上<=
,可以轻松实现。但是我想从总体上解决这个问题,所以我尝试了这种超级棘手的方法:
protocol RawRepresentableByInt {
var rawValue: Int { get }
}
extension RawRepresentableByInt {
static func <(lhs: RawRepresentableByInt, rhs: RawRepresentableByInt) -> Bool {
return lhs.rawValue < rhs.rawValue
}
static func >(lhs: RawRepresentableByInt, rhs: RawRepresentableByInt) -> Bool {
return lhs.rawValue > rhs.rawValue
}
static func <=(lhs: RawRepresentableByInt, rhs: RawRepresentableByInt) -> Bool {
return lhs.rawValue <= rhs.rawValue
}
static func >=(lhs: RawRepresentableByInt, rhs: RawRepresentableByInt) -> Bool {
return lhs.rawValue >= rhs.rawValue
}
}
// Error: Extension of protocol 'RawRepresentable' cannot have an inheritance clause
extension RawRepresentable: RawRepresentableByInt where RawValue == Int {
}
它产生一个编译器错误:
Error: Extension of protocol 'RawRepresentable' cannot have an inheritance clause
我觉得在逻辑上和Int
enum
相比,没有什么是无法实现的。请帮我欺骗 Swift 编译器。任何也需要此类扩展的人都可以参加。
这比我想象的要容易。所以,基本上你可以使用 Self
而不是创建一个额外的协议。
enum Difficulty: Int {
case Easy = 0
case Normal
case Hard
}
extension RawRepresentable where RawValue: Comparable {
static func <(lhs: Self, rhs: Self) -> Bool {
return lhs.rawValue < rhs.rawValue
}
static func >(lhs: Self, rhs: Self) -> Bool {
return lhs.rawValue > rhs.rawValue
}
static func <=(lhs: Self, rhs: Self) -> Bool {
return lhs.rawValue <= rhs.rawValue
}
static func >=(lhs: Self, rhs: Self) -> Bool {
return lhs.rawValue >= rhs.rawValue
}
}
let easy = Difficulty.Easy
print(easy > .Hard) // false