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