我习惯于将enum
s视为数值,因此使用诸如>
、<=
等运算符。对于大多数枚举来说,这可能不是必要的,但有一种情况是状态:
@objc public enum MyState: Int {
case Loading = 0
case Loaded
case Resolved
case Processed
}
我希望能够获取一个实例变量并检查:
var state: MyState = ...
if state > .Loaded {
...
}
但斯威夫特抱怨自己不知道该怎么做。我已将枚举声明为int。是否是比较
rawValue
s的唯一选项?我希望能避免这种情况,因为它会变得非常难看,而且斯威夫特自己也会很快接近它。 最佳答案
沿着这些线的东西不够吗?
enum State: Int, Comparable {
case Loading
case Loaded
case Resolved
case Processed
}
func < (lhs: State, rhs: State) -> Bool {
return lhs.rawValue < rhs.rawValue
}
let state = State.Resolved
state > .Loaded // true
请注意,由于
<
s已经相等,因此只需要实现enum
一般来说,
enums
的可比性独立于其原始值(如有),例如:enum State: Comparable {
case Good
case Bad
}
func < (lhs: State, rhs: State) -> Bool {
return lhs == .Bad && rhs == .Good
}
let state = State.Good
state > .Bad // true
第二种想法是,Swift确实允许我们扩展
RawRepresentable
协议,其确切效果是@devios正在寻找的:/// Extends all `RawRepresentable` enums with `Comparable` raw values,
/// such as `enum E : Int` or `enum E : String`...
///
public func < <E: RawRepresentable where E.RawValue : Comparable> (lhs: E, rhs: E) -> Bool {
return lhs.rawValue < rhs.rawValue
}
在扩展库中的某个地方,您只需要通过将类型声明为
Comparable
来显式地选择加入:enum N: Int, Comparable {
case Zero, One, Two, Three
}
enum S: String, Comparable {
case A, B, C, D
}
let n: N = .Two
n > .One // true
let ss: [S] = [.B, .A, .D, .C].sort() // [A, B, C, D]
如果通用行为不适合特定类型,那么这仍然允许您提供具体的实现:
func < (lhs: S, rhs: S) -> Bool {
return rhs.hashValue < lhs.hashValue // inverting the ordering
}
let ss: [S] = [.B, .A, .D, .C].sort() // [D, C, B, A]