Ich bin mit switch
Anweisungen in Swift vertraut , frage mich aber, wie ich diesen Code durch Folgendes ersetzen kann switch
:
if someVar < 0 {
// do something
} else if someVar == 0 {
// do something else
} else if someVar > 0 {
// etc
}
swift
switch-statement
Pieter
quelle
quelle
Antworten:
Hier ist ein Ansatz. Angenommen, es
someVar
handelt sich um eineInt
oder eine andereComparable
, können Sie den Operanden optional einer neuen Variablen zuweisen. Auf diese Weise können Sie den Umfang mit demwhere
Schlüsselwort festlegen, wie Sie möchten :Dies kann etwas vereinfacht werden:
Sie können das
where
Schlüsselwort auch mit der Bereichsübereinstimmung vollständig vermeiden :quelle
default: fatalError()
, mögliche Logikfehler frühzeitig zu erkennen.assertionFailure
scheint eine sicherere Option zu sein, insbesondere wenn Sie in einem Team arbeiten.Mit Swift 5 können Sie einen der folgenden Schalter auswählen, um Ihre if-Anweisung zu ersetzen.
# 1 Schalter mit
PartialRangeFrom
und verwendenPartialRangeUpTo
# 2 Schalter mit
ClosedRange
und verwendenRange
# 3 Verwenden von switch mit where-Klausel
# 4 Verwenden von switch mit where-Klausel und Zuweisung an
_
# 5 Verwenden des Switches mit
RangeExpression
dem~=(_:_:)
Operator des Protokolls# 6 Verwenden des Switches mit
Equatable
dem~=(_:_:)
Operator des Protokolls# 7 Verwendung Schalter mit
PartialRangeFrom
,PartialRangeUpTo
undRangeExpression
‚scontains(_:)
Verfahrenquelle
0.1
löst einen schwerwiegenden Fehler aus, da1...
nur Zahlen von 1 abgedeckt werden. Diese Lösung funktioniert also nur, wenn diesvalue
eineInt
ist. Dies ist jedoch gefährlich, da bei einer Änderung des Variablentyps die Funktionalität ohne Compilerfehler unterbrochen wird.Die
switch
Anweisung unter der Haube verwendet den~=
Operator. Also das:Desugars dazu:
Wenn Sie sich die Standardbibliotheksreferenz ansehen, können Sie genau
~=
wissen , wozu die überladen ist : Enthalten ist die Bereichsanpassung und das Gleichsetzen für gleichwertige Dinge. (Nicht enthalten ist der Enum-Case-Matching, bei dem es sich eher um eine Sprachfunktion als um eine Funktion in der Standardbibliothek handelt.)Sie werden sehen, dass es nicht mit einem geraden Booleschen Wert auf der linken Seite übereinstimmt. Für diese Art von Vergleichen müssen Sie eine where-Anweisung hinzufügen.
Es sei denn ... Sie überlasten den
~=
Bediener selbst. (Dies wird im Allgemeinen nicht empfohlen.) Eine Möglichkeit wäre etwa diese:Das entspricht also einer Funktion, die links einen Booleschen Wert an ihren Parameter rechts zurückgibt. Hier ist die Art von Dingen, für die Sie es verwenden könnten:
Für Ihren Fall haben Sie möglicherweise eine Aussage, die folgendermaßen aussieht:
Aber jetzt müssen Sie neue
isNegative
undisPositive
Funktionen definieren . Es sei denn, Sie überlasten einige weitere Operatoren ...Sie können normale Infix-Operatoren überladen, um Curry-Präfix- oder Postfix-Operatoren zu sein. Hier ist ein Beispiel:
Das würde so funktionieren:
Kombinieren Sie dies mit der früheren Funktion, und Ihre switch-Anweisung kann folgendermaßen aussehen:
Jetzt sollten Sie so etwas in der Praxis wahrscheinlich nicht verwenden: Es ist ein bisschen zwielichtig. Sie sind (wahrscheinlich) besser dran, sich an die
where
Aussage zu halten. Das heißt, das switch-Anweisungsmuster vonoder
Scheint häufig genug zu sein, um eine Überlegung wert zu sein.
quelle
Sie können:
quelle
Da jemand hier schon gepostet
case let x where x < 0:
hat ist eine Alternative für wosomeVar
ist einInt
.Und hier ist eine Alternative für wo
someVar
ist einDouble
:quelle
So sieht es mit Bereichen aus
quelle
Der
<0
Ausdruck funktioniert nicht mehr (mehr?), Also habe ich folgendes gefunden:Swift 3.0:
quelle
X_MAX
wird ersetzt durch.greatestFiniteMagnitude
, das heißtDouble.greatestFiniteMagnitude
,CGFloat.greatestFiniteMagnitude
etc. Also in der Regel können Sie nur tun ,case 0..< .greatestFiniteMagnitude
da die Art dersomeVar
bereits bekanntvar timeLeft = 100
switch timeLeft {case 0...<=7200: print("ok") default:print("nothing") }
Warum wird der<=
Betreiber nicht erkannt? Wenn ich es ohne das Gleiche schreibe, funktioniert es. Dankecase 0...7200:
Der Operator<=
ist ein Vergleichsoperator. In einem Schalter können Sie nur Bereichsoperatoren verwenden (siehe Dokumente)someVar
ein warInt
und ichDouble(
someVar) `ausführen musste, damit es funktioniert ...Ich bin froh, dass Swift 4 das Problem angeht:
Als Workaround in 3 habe ich:
Funktioniert aber nicht ideal
quelle