Znam switch
instrukcje w Swift, ale zastanawiam się, jak zamienić ten fragment kodu na switch
:
if someVar < 0 {
// do something
} else if someVar == 0 {
// do something else
} else if someVar > 0 {
// etc
}
swift
switch-statement
Pieter
źródło
źródło
Odpowiedzi:
Oto jedno podejście. Zakładając, że
someVar
jest toInt
lub innyComparable
, możesz opcjonalnie przypisać operand do nowej zmiennej. Dzięki temu możesz określić zakres, jak chcesz, używającwhere
słowa kluczowego:Można to nieco uprościć:
Możesz również
where
całkowicie uniknąć słowa kluczowego dzięki dopasowaniu zakresu:źródło
default: fatalError()
wczesne wykrywanie możliwych błędów logicznych.assertionFailure
wydaje się być bezpieczniejszą opcją, szczególnie podczas pracy w zespole.Dzięki Swift 5 możesz wybrać jeden z poniższych przełączników, aby zastąpić instrukcję if.
# 1 Używanie przełącznika z
PartialRangeFrom
iPartialRangeUpTo
# 2 Korzystanie z przełącznika z
ClosedRange
iRange
# 3 Używanie przełącznika z klauzulą WHERE
# 4 Używanie przełącznika z klauzulą WHERE i przypisaniem do
_
# 5 Używanie przełącznika z operatorem
RangeExpression
protokołu~=(_:_:)
# 6 Używanie przełącznika z operatorem
Equatable
protokołu~=(_:_:)
7 Korzystanie z przełącznika
PartialRangeFrom
,PartialRangeUpTo
aRangeExpression
jestcontains(_:)
metodaźródło
0.1
zgłasza błąd krytyczny, ponieważ1...
obejmuje tylko liczby od 1. Więc to rozwiązanie działa tylko wtedy, gdyvalue
jest,Int
ale jest to niebezpieczne, ponieważ jeśli typ zmiennej zostanie zmieniony, funkcjonalność zostanie przerwana bez żadnego błędu kompilatora.switch
Oświadczenie, pod maską, używa~=
operatora. Więc to:Cukry do tego:
Jeśli spojrzysz na odniesienie do biblioteki standardowej, może ci dokładnie powiedzieć, do czego
~=
jest przeciążona : dołączone jest dopasowywanie zakresu i zrównanie dla równych rzeczy. (Nie uwzględniono dopasowania wyliczenia wielkości liter, co jest funkcją języka, a nie funkcją w standardowej bibliotece)Zobaczysz, że nie pasuje do prostej wartości logicznej po lewej stronie. W przypadku tego rodzaju porównań należy dodać instrukcję gdzie.
Chyba że ... sam przeciążasz
~=
operatora. (Generalnie nie jest to zalecane) Jedną z możliwości byłoby coś takiego:Więc to dopasowuje funkcję, która zwraca wartość logiczną po lewej stronie do parametru po prawej stronie. Oto rodzaj rzeczy, do których możesz go użyć:
W twoim przypadku możesz mieć oświadczenie, które wygląda następująco:
Ale teraz musisz zdefiniować nowe
isNegative
iisPositive
funkcje. Chyba że przeładujesz więcej operatorów ...Możesz przeciążać zwykłe operatory wrostkowe, aby były one operatorami prefiksowymi lub postfiksowymi. Oto przykład:
To działałoby tak:
Połącz to z wcześniejszą funkcją, a instrukcja switch może wyglądać następująco:
Prawdopodobnie nie powinieneś używać tego typu rzeczy w praktyce: jest to trochę podejrzane. (Prawdopodobnie) lepiej trzymać się tego
where
stwierdzenia. To powiedziawszy, wzorzec instrukcji przełącznikalub
Wydaje się na tyle powszechne, że warto się nad tym zastanowić.
źródło
Możesz:
źródło
Ponieważ ktoś już opublikował
case let x where x < 0:
tutaj, jest alternatywą dla gdziesomeVar
jestInt
.A oto alternatywa dla gdzie
someVar
jestDouble
:źródło
Tak to wygląda z zakresami
źródło
<0
Wyrażenie nie działa (już?), Więc skończyło się w ten sposób:Swift 3.0:
źródło
X_MAX
została zastąpiona.greatestFiniteMagnitude
, tjDouble.greatestFiniteMagnitude
,CGFloat.greatestFiniteMagnitude
itd. Więc zwykle, można po prostu zrobićcase 0..< .greatestFiniteMagnitude
od rodzajusomeVar
jest już znanyvar timeLeft = 100
switch timeLeft {case 0...<=7200: print("ok") default:print("nothing") }
Dlaczego<=
operator nie jest rozpoznawany? Jeśli napiszę to bez równości, to działa. Dziękicase 0...7200:
Operator<=
jest operatorem porównania. W przełączniku możesz używać tylko operatorów zasięgu (patrz dokumentacja)someVar
byłInt
i musiałem zrobićDouble(
someVar) `, aby działał ...Cieszę się, że Swift 4 rozwiązuje problem:
Jako obejście w 3 zrobiłem:
Działa, ale nie jest idealny
źródło