Ca

Case in Crystal

1 Übung

Über Case

case (in anderen Sprachen oft als switch bezeichnet) ist eine Form von Kontrollausdruck, ähnlich wie if-else. Mit case lassen sich mehrere if-else-if-Anweisungen verketten. Das kann lesbarer sein und ermöglicht mächtige Konstrukte.

Eine case-Anweisung wird durch das Schlüsselwort case eingeleitet, auf das ein optionaler Ausdruck folgt. Für jeden Fall wird dann das Schlüsselwort when verwendet, gefolgt von einem Ausdruck, der mit dem Case-Ausdruck verglichen wird. Das Schlüsselwort when sollte nicht gegenüber dem Schlüsselwort case eingerückt werden. Nach dem Schlüsselwort when folgt der Code, der ausgeführt werden soll, wenn der Case-Ausdruck zum When-Ausdruck passt. Case erlaubt eine optionale else-Anweisung, die ausgeführt wird, wenn kein anderer Fall passt.

Der Case-Ausdruck wird ausgewertet und dann mit jedem When-Ausdruck verglichen. Der Vergleich erfolgt mit dem Subsumtionsoperator (===).

case 1
when 1
  puts "One"
when 2
  puts "Two"
else
  puts "Other"
end
# => One

# This is the same as:
tmp = 1
if 1 === tmp
  puts "One"
elsif 2 === tmp
  puts "Two"
else
  puts "Other"
end

Subsumtionsoperator (===)

Der Subsumtionsoperator (===) unterscheidet sich etwas vom Gleichheitsoperator (==). Der Operator prüft, ob die rechte Seite ein Element der Menge ist, die die linke Seite beschreibt. Das bedeutet, dass es eine Rolle spielt, wo die einzelnen Operanden stehen. Wie das funktioniert, hängt vom Typ der linken Seite ab. Ein Range prüft zum Beispiel, ob die rechte Seite im Bereich liegt, und ein Object prüft, ob die rechte Seite eine Instanz des Object ist.

(1..3) == 1  # => false
(1..3) === 1 # => true

String == "foo"  # => false
String === "foo" # => true

Case mit mehreren Ausdrücken

Cases ermöglichen es, mehrere Ausdrücke in einem einzigen Case abzugleichen, wobei die einzelnen möglichen Werte durch ein Komma getrennt werden. Der Code wird ausgeführt, wenn einer der Ausdrücke passt. Das kann bei einem einzelnen Case mit mehreren möglichen Werten nützlich sein.

case 1
when 1, 2
  puts "One or two"
else
  puts "Other"
end

Cases mit Bereichen

Cases können auch prüfen, ob ein Wert in einem Bereich liegt. Dazu verwendest du einen Bereich als When-Ausdruck.

case var
when 1..3
  puts "One to three"
else
  puts "Other"
end

Cases ohne Case-Ausdruck

Wenn kein Case-Ausdruck benötigt wird, kannst du ihn weglassen. Dadurch wird jeder When-Ausdruck auf seinen Wahrheitswert geprüft. Und sie verhalten sich dann wie if-else-if-Anweisungen.

case
when 1 == 1
  puts "One is equal to one"
when 1 > 2
  puts "One is greater than two"
else
  puts "Other"
end

Einzeiliges When

Crystal erlaubt einzeilige Case-Anweisungen. Das ist praktisch, wenn du eine einfache einzeilige Anweisung hast. In der einzeiligen Form schreibst du die Anweisung als when <expression> then <statement>. In der Else-Anweisung schreibst du sie als else <statement>.

case var
when 1 then puts "One"
when 2 then puts "Two"
else puts "Other"
end

Case mit Typen

Case ermöglicht den Abgleich mit Typen. Der Vergleich verwendet den Operator is_a?, um den Typ der Variable zu prüfen. So lässt sich zum Beispiel für jeden Typ in einem Union-Typ ein eigener Zweig anlegen.

case var
when Int32
  puts "Int32"
when String
  puts "String"
else
  puts "Other"
end

Implizites Objekt

Case erlaubt die Verwendung eines impliziten Objekts. So kann ein When-Ausdruck zum Beispiel ein Methodenaufruf auf dem Case-Ausdruck sein. Je nachdem, ob die Methode einen wahren oder falschen Wert zurückgibt, passt der Case oder nicht.

case 1
when .odd?
  puts "Odd"
when .even?
  puts "Even"
end

Exhaustiver Case

Case ermöglicht exhaustive Cases. Das bedeutet, dass du sicherstellen kannst, dass alle möglichen Werte behandelt werden. Es ähnelt der When-Anweisung, verwendet aber das Schlüsselwort in statt when. Ein exhaustiver Case unterstützt keine when- oder else-Anweisungen.

Exhaustive Cases können auf Bools, Union-Typen, Enum und Tuples angewendet werden. Die beiden letztgenannten werden in späteren Konzepten behandelt.

Exhaustive Cases bedeuten, dass alle Möglichkeiten behandelt werden müssen. Andernfalls gibt es einen Kompilierfehler. Union-Typen in einem exhaustiven Case zu behandeln, ähnelt einem nicht-exhaustiven Case.

var : (Int32 | String | Bool)
case var 
in Int32
  puts "Int32"
in String
  puts "String"
in Bool
  puts "Bool"
end

Bools lassen sich als exhaustiver Case behandeln, indem du die Schlüsselwörter true und false verwendest.

var : Bool
case var
in true
  puts "True"
in false
  puts "False"
end
Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab

Lerne Case

Das Üben ist gesperrt

Schalte 6 weitere Übungen frei, um Case zu üben