Подтвердить что ты не робот

НЕ условие в выражении "if case"

У меня есть перечисление:

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 работает, если случаи не имеют связанных значений, но если они выполняют оператор ==, необходимо перегрузить. Извините, что не разъяснял это в первую очередь.

4b9b3361

Ответ 1

Этот "ответ" - это не что иное, как сжатие вашего неудобного решения. Если вам все равно, когда значение не соответствует определенному значению перечисления, вы можете записать его так, как это все в одной строке, с помощью else сразу же после предложения empty 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")
}

Ответ 2

Вы используете 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")
}

Extended:

Чтобы заставить его работать со связанными значениями, вам необходимо реализовать Equatable protocol, например:

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
    }
}

Конечно, вы должны обрабатывать все возможности, но я думаю, что у вас есть идея.

Extended:

Я не получаю ваш комментарий, но это работает для меня хорошо:

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")
}

Ответ 3

Нет ответов, еще упоминающих инструкцию guard, введенную Swift 2, которая является аккуратным дополнением к приведенным выше инструментам и, если вы спросите меня, самое чистое решение, если вы можете жить с требованием return от вашей функции или закрытия в else -block:

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

Подробнее см. Apple" Быстрый язык программирования (Swift 2.2): Statementments.