Развертывание нескольких опций в выражении if
Я хочу развернуть два варианта в одном выражении if, но компилятор жалуется на ожидаемое выражение после оператора в константе пароля.
В чем может быть причина?
if let email = self.emailField?.text && let password = self.passwordField?.text
{
//do smthg
}
Выполнено в Swift.
Ответы
Ответ 1
Отличные новости. Развертывание нескольких опций в одной строке теперь поддерживается в Swift 1.2 (XCode 6.3 beta, выпущен 2/9/15).
Больше не требуется сопоставление шаблонов кортежей/переключателей. Это действительно очень близко к вашему оригинальному предложенному синтаксису (спасибо за прослушивание, Apple!)
if let email = emailField?.text, password = passwordField?.text {
}
Еще одна приятная вещь: вы можете добавить where
для "условия охраны":
var email: String? = "[email protected]"
var name: String? = "foo"
if let n = name, e = email where contains(e, "@") {
println("name and email exist, email has @")
}
Ссылка: Замечания к выпуску XCode 6.3 Beta
Ответ 2
Обновление для Swift 3:
if let email = emailField?.text, let password = passwordField?.text {
}
Каждой переменной теперь должно предшествовать ключевое слово let
Ответ 3
Как насчет обертывания опций в кортеже и использования совпадения с шаблоном?
switch (self.emailField?.text, self.passwordField?.text) {
case let (.Some(email), .Some(password)):
// unwrapped 'email' and 'password' strings available here
default:
break
}
Это определенно немного шумнее, но по крайней мере его также можно комбинировать с предложением where.
Ответ 4
Использование
if let x = y {
}
не эквивалентно
if (let x = y) { // this is actually not allowed
}
", если пусть" эффективно является ключевым словом из двух слов, что эквивалентно
if y != nil {
let x = y!
// rest of if let block
}
Ответ 5
До Swift 1.2
Подобно @James, я также создал функцию unwrap
, но вместо нее используется существующий if let
для потока управления, а не для закрытия:
func unwrap<T1, T2>(optional1: T1?, optional2: T2?) -> (T1, T2)? {
switch (optional1, optional2) {
case let (.Some(value1), .Some(value2)):
return (value1, value2)
default:
return nil
}
}
Это можно использовать так:
if let (email, password) = unwrap(self.emailField?.text, self.passwordField?.text)
{
// do something
}
От: https://gist.github.com/tomlokhorst/f9a826bf24d16cb5f6a3
Обратите внимание, что если вы хотите обрабатывать больше случаев (например, когда одно из двух полей равно nil), вам лучше сделать оператор switch
.
Ответ 6
Я не могу объяснить, почему приведенный выше код не работает, но это будет хорошей заменой:
if let email = self.emailField?.text
{
if let password = self.passwordField?.text
{
//do smthg
}
}
Ответ 7
На основе ответа @Joel я создал вспомогательный метод.
func unwrap<T, U>(a:T?, b:U?, handler:((T, U) -> ())?) -> Bool {
switch (a, b) {
case let (.Some(a), .Some(b)):
if handler != nil {
handler!(a, b)
}
return true
default:
return false
}
}
//Использование
unwrap(a, b) {
println("\($0), \($1)")
}