Je veux décompresser deux options dans une instruction if, mais le compilateur se plaint d'une expression attendue après l'opérateur à la constante du mot de passe . Quelle pourrait être la raison?
if let email = self.emailField?.text && let password = self.passwordField?.text
{
//do smthg
}
Fait à Swift.
Bonne nouvelle. Le décompression de plusieurs options sur une seule ligne est désormais prise en charge dans Swift 1.2 (XCode 6.3 beta, publié le 9/09/15).
Aucune correspondance de motif de tuple/commutateur n'est nécessaire. C'est en fait très proche de la syntaxe proposée à l'origine (merci de votre écoute, Apple!)
if let email = emailField?.text, password = passwordField?.text {
}
Une autre bonne chose est que vous pouvez également ajouter where
pour une "condition de sauvegarde":
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 @")
}
Référence: Notes de publication de XCode 6.3 Beta
Mise à jour pour Swift 3:
if let email = emailField?.text, let password = passwordField?.text {
}
chaque variable doit maintenant être précédée d'un mot clé let
Pourquoi ne pas encapsuler les options dans un tuple et utiliser switch to pattern pattern?
switch (self.emailField?.text, self.passwordField?.text) {
case let (.Some(email), .Some(password)):
// unwrapped 'email' and 'password' strings available here
default:
break
}
C'est certainement un peu plus bruyant, mais au moins, il pourrait également être combiné avec une clause where .
L'usage
if let x = y {
}
n'est pas équivalent à
if (let x = y) { // this is actually not allowed
}
"si let" est effectivement un mot clé de deux mots, équivalent à
if y != nil {
let x = y!
// rest of if let block
}
Avant Swift 1.2
Comme @James, j'ai également créé une fonction unwrap
, mais celle-ci utilise le if let
existant pour le flux de contrôle, au lieu d'utiliser une fermeture:
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
}
}
Cela peut être utilisé comme suit:
if let (email, password) = unwrap(self.emailField?.text, self.passwordField?.text)
{
// do something
}
De: https://Gist.github.com/tomlokhorst/f9a826bf24d16cb5f6a3
Notez que si vous souhaitez gérer davantage de cas (comme lorsque l'un des deux champs is nil), il vaut mieux utiliser une instruction switch
.
Swift 4
if let suggestions = suggestions, let suggestions1 = suggestions1 {
XCTAssert((suggestions.count > suggestions1.count), "TEST CASE FAILED: suggestion is nil. delete sucessful");
}
Je ne peux pas expliquer pourquoi le code ci-dessus ne fonctionne pas, mais ce serait un bon remplacement:
if let email = self.emailField?.text
{
if let password = self.passwordField?.text
{
//do smthg
}
}
Basé sur la réponse de @ Joel, j'ai créé une méthode d'assistance.
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
}
}
// utilisation
unwrap(a, b) {
println("\($0), \($1)")
}