2017-01-29 3 views
1

Was ich versuche zu erreichen ist dies - ich habe zwei Textfelder und ich möchte print() eine Nachricht an die Konsole, wenn der Benutzername Textfeld .isEmpty oder wenn das Passwort-Feld .isEmpty. Das erste, was mir aufgefallen ist, ist, dass die Textfelder optional sind, da sie natürlich leer sein können. Könnte mir also jemand die Syntax und die Argumentation hinter den folgenden Codebeispielen erklären?Optionals und Unwrapping

Q1: Warum muss ich nach der .isEmpty auspacken?

if(self.username.text?.isEmpty)! { 
    print("Something!") 
} 

Q2: Warum funktioniert diese Syntax nicht, wenn Sie einen oder -Operator einschließen?

if(self.username.text?.isEmpty || self.password.text?.isEmpty)! { 
    print("Please provide username and password!") 
} 

Q3: Warum kann ich nicht direkt nach dem auspacken .isEmpty?

if(self.username.text?.isEmpty! || self.password.text?.isEmpty!) { 
    print("Please provide username and password!") 
} 
+1

Dies könnte helfen: [Optional Chaining Reference] (https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html) – nathan

Antwort

0

Q1: Warum muss ich nach dem .isEmpty auspacken?

if(self.username.text?.isEmpty)! { 
    print("Something!") 
} 

Die if Aussage Struktur zwingt Sie true/false im Körper zu haben, zu vereinfachen:

let condition = false 

if condition {...} 

Wenn Sie diese Anweisung auszupacken self.username.text?.isEmpty Sie den Compiler „Ich sagen versprechen, dass es nie ist nil "sogar, dass es sein könnte.

Q2: Warum funktioniert diese Syntax nicht, wenn Sie einen oder -Operator einschließen?

Aus dem gleichen Grunde wie vor dem Eingang für or/and Betreiber muss nicht nil (ungeöffnete) sein.

Beachten Sie die folgende Zeile. Wenn Sie versuchen, diese Anweisung auszuwerten, werden Sie feststellen, dass Sie versuchen, einen booleschen Wert mit zwei Optionals als Parameter auszupacken.

if(self.username.text?.isEmpty || self.password.text?.isEmpty)! { 

Q3: Warum kann ich nicht direkt nach dem .isEmpty auspacken?

Ich rate hier, basierend auf dem Problem, das Sie vorgestellt haben.

isEmpty ist keine optionale, es kann wahr/falsch sein, daher kann nicht ausgepackt werden.

Diese Anweisung self.username.text?.isEmpty ist optional, sie kann true/false/nil sein und kann ausgepackt werden.

Ich hoffe, es hilft, die Dinge klarer zu machen. Das Lesen von optionals und das Analysieren von Apples Code-Beispielen könnte noch mehr helfen.

2

Q1: Sie müssen auspacken, weil die text Eigenschaft nil sein kann. Vielleicht weil es ein gültiger Wert ist, vielleicht weil es ein Artefakt der Objective-C-Konvertierung ist und es wirklich nil_resettable ist.

Die Verwendung von ! ist unsicher, da es beim Zugriff auf den Text zum Absturz kommen kann, wenn es nicht aktiviert ist.

so etwas wie dies

if self.username.text?.isEmpty == false { 
    print("Something!") 
} 

Swift hat eine implizite nicht optional optional Förderung Versuchen Sie, wenn der erforderliche Typ ist optional.

Zuerst war es Bool? == Bool und es wurde geändert Bool? == Bool?

Q2: Warum diese Syntax nicht, wenn Sie einen oder Betreiber enthalten?

let a: Bool? = self.username.text?.isEmpty 
let b: Bool? = self.password.text?.isEmpty 
let c = a || b // the problem here is that `Bool?` doesn't implement 
       // the operator `||` as it's not clear how this would 
       // work with optionals. 

Sie tun möchten:

guard let username = self.username.text, 
    let password = self.password.text, 
    !username.isEmpty, 
    !password.isEmpty { 

    print("Please provide username and password!") 
    return 
} 

// code using username as String and password as String (not optionals) 

Q3:

Sie benötigen eine Einklammerung zu beheben.

if (self.username.text?.isEmpty)! || (self.password.text?.isEmpty)! { 
    print("Please provide username and password!") 
} 

Bitte vergessen Sie nicht, ! im Produktionscode zu verwenden. Dies ist unsicher. Verwenden Sie die Variante von Q2.