迅速的不平等

时间:2016-03-29 23:08:32

标签: swift enums

我以前能够将enum视为数值,因此会使用><=等运算符。对于大多数枚举用途,这可能是不是那么必要,但有一种情况是:

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

我希望能够获取一个实例变量并检查它:

var state: MyState = ...
if state > .Loaded {
    ...
}

但斯威夫特抱怨它不知道该怎么做。我已将enum声明为Int。我唯一的选择是比较rawValue?我本来希望避免这种情况,因为它会变得非常丑陋,Swift会自己接近 sooo

3 个答案:

答案 0 :(得分:4)

沿着这些界限的东西不会足够吗?

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

请注意,由于<已经等同,因此只需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]

答案 1 :(得分:0)

我不完全确定你想要什么,但有两种方法可以解决这个问题,其中一种方法是你已经提到的,它使用原始值。

另一种方法是使用Comparable协议。您可以使枚​​举符合协议并实现四种方法(&lt;是必需的,&gt;,&lt; =和&gt; =是可选的):

enum MyState: Int, Comparable {
    ...
}

func < (lhs: MyState, rhs: MyState) -> Bool {
    return lhs.rawValue < rhs.rawValue
}

// add other three protocol methods if needed

然后你可以像整数一样比较它们:

if someState > .Loading {
    ...
}

答案 2 :(得分:0)

为枚举实现不同的逻辑运算符。无需使用Equatable或Comparable

enum State: Int
{    
  case Loading
  case Loaded
  case Resolved
  case Processed
}

func < (lhs: State, rhs: State) -> Bool 
{
  return lhs.rawValue < rhs.rawValue
}

func > (lhs: State, rhs: State) -> Bool 
{
  return lhs.rawValue > rhs.rawValue
}