web-dev-qa-db-de.com

Gute Kodierungspraxis: Wenn Anweisung mit optionalem Typ Bool

Ich habe also eine App in Swift entwickelt und heute verbrachte ich fast eine Stunde damit, ein Problem zu debuggen, das sich als völlig unerwartet erwies. Es ergab sich alles aus dem folgenden Code.

if (hero.isAI) { //isAI is a Bool

}

Das Problem war, dass diese if-Anweisung IMMER true zurückgab. Also dachte ich, dass ich vielleicht isAI irgendwo auf wahr gesetzt habe, aber am Ende wurde mir klar, dass ich isAI als optionalen Typ deklariert habe, wie unten gezeigt.

var isAI: Bool!

wann es hätte sein sollen

var isAI: Bool

Dies führte dazu, dass die if-Anweisung nicht prüfte, ob isAI wahr ist, sondern stattdessen prüfte, ob sie einen Wert enthielt.

Um jetzt sicher zu gehen, schreibe ich meine if-Statements so 

if (hero.isAI == true) { //isAI is a Bool

}

Meine Frage ist also Was sind meine Optionen, um dieses Problem in der Zukunft zu vermeiden? (Dieses Problem scheint äußerst gefährlich zu sein, insbesondere wenn Sie in einem großen Projekt an einem Team arbeiten). Soll ich meine if-Anweisung immer explizit schreiben, sollte ich den optionalen Typ für Bools einfach ganz meiden?

Beachten Sie, dass dieses Problem in Xcode Beta 2 nicht aufgetreten ist. Dieses Problem trat auf, als ich auf Xcode Beta 3 aufrief. Ich denke, in Apple 2 hat Apple das implizit unverpackte Bool in einer if-Anweisung gehandhabt, indem der Wert überprüft wurde, statt dessen zu prüfen enthält einen Wert.

Nachstehend ein Beispiel, welche if-Anweisungen mit einem optionalen Bool ausgeführt werden, um das Problem besser zu verstehen.

let myBool: Bool! = false

if (myBool) {
    //Runs
}

if (myBool!) {
    //Won't Run
}

if (!myBool) {
    //Runs
}

if (myBool == true) {
    //Won't Run
}
11
Epic Byte

Dies ist ein bekanntes Problem, das im SwiftInFlux repo nachverfolgt wird, das dieses Zitat von Chris Lattner in den Apple Entwicklerforen enthält.

Dieses Problem tritt bei jedem optionalen Element auf, das Des LogicValue-Protokolls entspricht (z. B. verschachtelte Optionals, optional bool, Usw.). Wir halten es für ein ernstes Problem, das für 1.0 behoben werden muss und Einige Ideen hat, aber noch keine Lösung gefunden hat.

Daher betrifft dieses Problem nicht nur optionale Bools, sondern jeden optionalen Typ, der dem LogicValue-Protokoll entspricht (definiert als).

protocol LogicValue {
    func getLogicValue() -> Bool
}

Soweit es Empfehlungen gibt, wie man dies umgehen kann, ist es schwierig, eine bestimmte Lösung zu empfehlen, wenn man bedenkt, dass Apple keine Hinweise darauf gegeben hat, wie sie dies in der Zukunft lösen wollen, aber ich könnte mir vorstellen, dass dies weiterhin explizit überprüft wird Der Wert des Bool wäre der Weg zu gehen.

if (hero.isAI == true) {
    // stuff    
}

Nach einiger Lektüre liest sich das Zitat weiter wie folgt:

Für diesen allgemeinen Fall wäre die einfachste Antwort die Erzeugung einer Warnung Für "wenn x" und die explizite Schreibweise "wenn x! = Nil" oder "wenn x == wahr". um es explizit zu machen, was sie wollen.

11
Mick MacCallum

mein Rat ist, diese schöne Koaleszenz ?? zu verwenden.

if textfieldDate.text?.isEmpty ?? true {
    // the text is either nil or empty but its all we want to know
}
3
Nicolas Manzini

Wenn der Bool Teil von Core Data (auch bekannt als NSNumber) ist, sollten Sie es so machen.

if (isHero.isAI?.boolValue != nil)

Grüße

0
Cristian Pena