2017-05-21 29 views
2

如何在case具有关联值时测试枚举相等性?一个人为的例子:测试枚举for for equal for for ... where子句

enum Status : Equatable { 
    case success 
    case failed(error: String) 

    static func == (lhs: Status, rhs: Status) -> Bool { 
     switch (lhs, rhs) { 
     case (.success, .success), (.failed, .failed): 
      return true 
     default: 
      return false 
     } 
    } 
} 

let statuses = [ 
    Status.success, 
    .failed(error: "error 1"), 
    .failed(error: "error 2"), 
    .success 
] 

// Failed: Binary operator '==' cannot be applied to operands of type 'Status' and '_' 
for s in statuses where s == .failed { 
    print(s) 
} 

(我知道我可以测试s != .success,但实际的枚举具有更多的情况下,所以他们是一个麻烦)

+2

因为你认为任何'失败'等于另一个(这很奇怪;如果'error'是相同的,通常它们是相同的),你可以在s ==的状态下执行s。失败(错误:“”){...}'。请注意,使用'if',你可以做'if case',例如'如果case .failed = someStatus {...}'。 – Rob

+1

如果你不介意在过程中提取关联的值,你可以在case {fa(let)str){print(“failure:\(str)”)}'中做。 – vacawama

+1

这在某种程度上是开玩笑的,但它确实有效:'用于在zip(状态,状态){print(s)}'情况下(.failed,let s)''。 – vacawama

回答

3

您可以使用if case

for status in statuses { 
    if case .failed = status { 
     ... 
    } 
} 

但是,不幸的是,您不能使用casefor循环的where子句。


在这种情况下,虽然,因为你已经定义.failed等于另一无论error关联的值是什么,你理论上可以这样做:

for status in statuses where status == .failed(error: "") { 
    show("\(status)") 
} 

我没疯因为(a)它取决于.failed值相等的事实,即使它们具有不同的error关联值;和(b)它导致容易被误解的代码。