Einige großbildliche Perspektiven, um den anderen nützlichen, aber detailzentrierten Antworten hinzuzufügen:
In Swift erscheint das Ausrufezeichen in verschiedenen Kontexten:
- Forced Unwrapping:
let name = nameLabel!.text
- Implicitly unwrapped Optionals:
var logo: UIImageView!
- Forced Casting:
logo.image = thing as! UIImage
- Unerwünschte Ausnahmen:
try! NSJSONSerialization.JSONObjectWithData(data, [])
Jedes dieser Konstrukte ist eine andere Sprachkonstruktion mit einer anderen Bedeutung, aber sie haben alle drei wichtige Dinge gemeinsam:
1. Ausrufezeichen umgehen die Fehlerbehandlungsprüfungen von Swift zur Kompilierzeit.
Wenn Sie in Swift !
verwenden, sagen Sie im Grunde genommen: "Hey, Compiler, ich weiß, du denkst, dass hier möglicherweise ein Fehler passieren könnte, aber ich weiß mit absoluter Sicherheit, dass es nie passieren wird."
(Bearbeitung zur Klarstellung: Das erzwungene Entpacken mit !
ist immer noch "sicher" im Sinne des Sprachdesigns, dass es kein undefiniertes Verhalten ist und garantiert in einer sauberen, vorhersehbaren Weise abstürzt (im Gegensatz zum Dereferenzieren eines Null-Zeigers in C oder C++). Es ist jedoch nicht "sicher" im Sinne des App-Entwicklers, dass die Sprache sicherstellt, dass Ihre App nicht plötzlich wegen Ihrer falschen Annahmen abstürzt.)
Nicht alle gültigen Codes passen in das Schema des statischen Typsystems von Swift – oder in das statische Typenprüfung irgendeiner Sprache, um genau zu sein. Es gibt Situationen, in denen Sie logisch beweisen können, dass ein Fehler nie passieren wird, aber Sie können es dem Compiler nicht beweisen. Deshalb haben die Designer von Swift diese Funktionen von Anfang an hinzugefügt.
Jedoch, wenn Sie !
verwenden, schließen Sie aus, einen Wiederherstellungsweg für einen Fehler zu haben, was bedeutet, dass…
2. Ausrufezeichen sind potenzielle Abstürze.
Ein Ausrufezeichen sagt auch: "Hey Swift, ich bin so sicher, dass dieser Fehler niemals passieren kann, dass es besser für dich ist, meine ganze App zum Absturz zu bringen, als dass ich einen Wiederherstellungsweg dafür programmiere."
Das ist eine gefährliche Behauptung. Es kann die richtige sein: In kritischen Codebereichen, in denen Sie sorgfältig über die Invarianten Ihres Codes nachgedacht haben, kann es sein, dass fehlerhafte Ausgaben schlimmer sind als ein Absturz.
Jedoch, wenn ich !
in freier Wildbahn sehe, wird es selten so bewusst verwendet. Stattdessen bedeutet es allzu oft: "Dieser Wert war optional und ich habe nicht wirklich darüber nachgedacht, wieso er nil sein könnte oder wie ich diese Situation ordnungsgemäß behandeln sollte, aber durch das Hinzufügen von !
wurde es kompiliert … also ist mein Code korrekt, oder?"
Hüten Sie sich vor der Arroganz des Ausrufezeichens. Stattdessen…
3. Ausrufezeichen sollten sparsam verwendet werden.
Jedes dieser !
-Konstrukte hat ein Gegenstück mit ?
, das Sie zwingt, mit dem Fehler/nil-Fall umzugehen:
- Bedingtes Entpacken:
if let name = nameLabel?.text { ... }
- Optionals:
var logo: UIImageView?
- Bedingte Casts:
logo.image = thing as? UIImage
- Nil-bei-Fehler Ausnahmen:
try? NSJSONSerialization.JSONObjectWithData(data, [])
Wenn Sie versucht sind, !
zu verwenden, ist es immer gut, sorgfältig zu überlegen, warum Sie nicht stattdessen ?
verwenden. Ist das Abstürzen Ihres Programms wirklich die beste Option, wenn die !
-Operation fehlschlägt? Warum ist dieser Wert optional/fehlbar?
Gibt es einen vernünftigen Wiederherstellungsweg, den Ihr Code im nil/Fehlerfall nehmen könnte? Wenn ja, programmieren Sie es.
Wenn es unmöglich ist, dass es nil ist, dass der Fehler niemals passieren kann, gibt es dann einen vernünftigen Weg, Ihre Logik umzuarbeiten, so dass der Compiler das weiß? Falls ja, tun Sie es; Ihr Code wird fehleranfälliger sein.
Es gibt Zeiten, in denen es keinen vernünftigen Weg gibt, mit einem Fehler umzugehen, und den Fehler zu ignorieren – und somit mit falschen Daten fortzufahren – wäre schlimmer als abzustürzen. Das sind die Zeiten, in denen Sie das erzwungene Entpacken verwenden sollten.
Ich suche regelmäßig meinen gesamten Codebestand nach !
und überprüfe jede Verwendung davon. Sehr wenige Verwendungen halten einer Überprüfung stand. (Zum Zeitpunkt des Schreibens hat das gesamte Siesta-Framework genau zwei Instanzen davon.)
Das heißt nicht, dass Sie nie !
in Ihrem Code verwenden sollten – nur, dass Sie es bewusst verwenden sollten und es niemals zur Standardoption machen sollten.