我以前能够将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 。
答案 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
}