如果情况不符合条件'声明

时间:2015-11-12 16:30:56

标签: swift

我有一个枚举:

enum E {
    case A, B, C(Int)
}

let a: E = .A

这是我如何检查a是否等于.B

if case .B = a {
    // works fine
}

但我如何检查相反的情况? (a 等于.B)?这就是我的尝试:

if case .B != a { // Variable binding in a condition requires an initializer
    // ...
}

if !(case .B = a) { // Expected ',' separator
    // ...
}

当然,我可以这样做:

if case .B = a {
    // ...
} else {
    // put your code here
}

但这很尴尬,并且使用switch语句。还有更好的选择吗?

编辑:如果案例没有关联值,则解决方案@Greg建议有效,但如果==运算符需要重载。很抱歉没有在第一时间澄清这一点。

5 个答案:

答案 0 :(得分:23)

这个“答案”只不过是以更紧凑的方式编写尴尬解决方案。如果你只关心一个值不是某个枚举值的情况,你可以像这样把它写成一行,else紧跟在空的then子句之后:

enum E {
    case A, B(String), C(Int)
}

let a: E = .B("Hello")

if case .A = a {} else {
    print("not an A")
}

if case .B = a {} else {
    print("not a B")
}

if case .C = a {} else {
    print("not a C")
}

答案 1 :(得分:7)

您正在使用single = sign,这是一个赋值运算符。你必须使用double ==这是一个比较而且没有用例.A,使用E.A是正确的方法:

if E.A == a {
    // works fine
    print("1111")
}

if E.B != a {
    // works fine
    print("2222")
}

if E.B == a {
    // works fine
    print("3333")
}

扩展:

要使其与关联值一起使用,您必须实现Equatable协议,例如:

extension E: Equatable {}
func ==(lhs: E, rhs: E) -> Bool {
    switch (lhs, rhs) {
        case (let .C(x1), let .C(x2)):
            return x1 == x2
        case (.A, .A):
        return true

     default:
         return false
    }
}

当然,你必须处理所有的可能性,但我认为你有一个想法。

扩展:

我没有收到您的评论,但这对我很有用:

enum E {
    case A, B, C(Int)
}

extension E: Equatable {}
func ==(lhs: E, rhs: E) -> Bool {
    switch (lhs, rhs) {
        case (let .C(x1), let .C(x2)):
            return x1 == x2
        case (.A, .A):
            return true
        case (.B, .B):
            return true

     default:
         return false
    }
}

let a: E = .A
let b: E = .B
let c: E = .C(11)

if E.A == a {
    // works fine
    print("aaa true")
}
if E.A != a {
    // works fine
    print("aaa false")
}

if E.B == b {
    // works fine
    print("bbb true")
}

if E.B == b {
    // works fine
    print("bbb false")
}

if E.C(11) == c {
    // works fine
    print("ccc true")
}

if E.C(11) != c {
    // works fine
    print("1 ccc false")
}

if E.C(22) != c {
    // works fine
    print("2 ccc false")
}

答案 2 :(得分:6)

还没有任何答案提到由Swift 2引入的guard声明,这是上述工具的一个简洁的补充,如果你问我,如果你可以忍受,那么最干净的解决方案在return - 块中对else的函数或闭包的要求:

guard case .B = a else {
    // a does not match .B
    return
}

有关详细信息,请参阅Apple's "The Swift Programming Language (Swift 2.2): Statements"

答案 3 :(得分:0)

无法取消.case语句。但是,您可以使用正常比较,如下所示:

if a != .B {

}

在我看来,这是最直接的写作方式。

答案 4 :(得分:0)

我看到了警卫的回答,尽管我可以改善它。

请注意do块的命名方式。 我的意思是,它有效

i: do { guard case .B = a else {
    print("foo")
break i }}

当然可以,它要小得多:if case .B = a {} else { *** }


如果您确实想要那个!运算符,可以使用它

func cases<T: Equatable>(_ a: T,_ b: T) -> Bool { return a == b }
if cases(.B, a) {}
if !cases(.B, a) {}