Swift: тестирование опционального значения в корпусе коммутатора
В Swift, как я могу написать случай в инструкции switch, которая проверяет значение, которое переключается на содержимое опционального, пропуская регистр, если опция содержит nil
?
Вот как я могу себе представить, что это может выглядеть:
let someValue = 5
let someOptional: Int? = nil
switch someValue {
case someOptional:
// someOptional is non-nil, and someValue equals the unwrapped contents of someOptional
default:
// either, someOptional is nil, or someOptional is non-nil but someValue does not equal the unwrapped contents of someOptional
}
Если я просто напишу это точно так, компилятор жалуется, что someOptional
не разворачивается, но если я явным образом развожу его, добавив !
в конец, я, конечно же, получу ошибку времени выполнения someOptional
содержит nil
. Добавление ?
вместо !
мне показалось бы (в духе необязательной цепочки, я полагаю), но не исключает ошибки компилятора (т.е. Фактически не разворачивает необязательный).
Ответы
Ответ 1
Необязательно это просто enum
вот так:
enum Optional<T> : Reflectable, NilLiteralConvertible {
case None
case Some(T)
// ...
}
Таким образом, вы можете сопоставлять их как обычно "Соответствующие значения" с шаблонами соответствия:
let someValue = 5
let someOptional: Int? = nil
switch someOptional {
case .Some(someValue):
println("the value is \(someValue)")
case .Some(let val):
println("the value is \(val)")
default:
println("nil")
}
Если вы хотите совпадения из someValue
, используйте защитное выражение:
switch someValue {
case let val where val == someOptional:
println(someValue)
default:
break
}
А для Swift> 2.0
switch someValue {
case let val where val == someOptional:
print("matched")
default:
print("didn't match; default")
}
Ответ 2
Начиная с Xcode 7 (из примечаний к выпуску бета-версии 1), "новый шаблон x?
может использоваться для сопоставления с дополнительными параметрами в качестве синонима для .Some(x)
". Это означает, что в Xcode 7 и более поздних версиях также будет работать следующий вариант ответа rintaro :
let knownValue = 5
switch someOptional {
case knownValue?:
// Contents of someOptional are knownValue, defined above.
case let otherValue?:
// Contents of someOptional are *any* non-nil value not already tested for.
// Unwrapped contents are assigned to otherValue for use inside this case.
default:
// someOptional is nil.
}
Ответ 3
В Swift 4 вы можете использовать Необязательно: ExpressibleByNilLiteral Apple для переноса необязательного
https://developer.apple.com/documentation/swift/optional
Пример
enum MyEnum {
case normal
case cool
}
некоторые
let myOptional: MyEnum? = MyEnum.normal
switch smyOptional {
case .some(.normal):
// Found .normal enum
break
case .none:
break
default:
break
}
нени
let myOptional: MyEnum? = nil
switch smyOptional {
case .some(.normal):
break
case .none:
// Found nil
break
default:
break
}
по умолчанию
let myOptional: MyEnum? = MyEnum.cool
switch smyOptional {
case .some(.normal):
break
case .none:
break
default:
// Found .Cool enum
break
}
Перечисление со значением
enum MyEnum {
case normal(myValue: String)
case cool
}
некоторая ценность
let myOptional: MyEnum? = MyEnum.normal("BlaBla")
switch smyOptional {
case .some(.normal(let myValue)) where myValue == "BlaBla":
// Here because where find in my myValue "BlaBla"
break
// Example for get value
case .some(.normal(let myValue)):
break
// Example for just know if is normal case enum
case .some(.normal):
break
case .none:
break
default:
break
}