我习惯于将enums视为数值,因此使用诸如><=等运算符。对于大多数枚举来说,这可能不是必要的,但有一种情况是状态:

@objc public enum MyState: Int {
    case Loading = 0
    case Loaded
    case Resolved
    case Processed
}

我希望能够获取一个实例变量并检查:
var state: MyState = ...
if state > .Loaded {
    ...
}

但斯威夫特抱怨自己不知道该怎么做。我已将枚举声明为int。是否是比较rawValues的唯一选项?我希望能避免这种情况,因为它会变得非常难看,而且斯威夫特自己也会很快接近它。

最佳答案

沿着这些线的东西不够吗?

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]

10-04 10:47