case (spesso chiamato switch in altri linguaggi) è una forma di espressione di controllo, come if-else.
case permette di concatenare più istruzioni if-else-if, può essere più leggibile e consente costrutti potenti.
Un case è definito dalla parola chiave case, seguita da un'espressione facoltativa.
Poi, per ogni caso, si usa la parola chiave when seguita da un'espressione che viene confrontata con l'espressione del case.
La parola chiave when non va indentata rispetto alla parola chiave case.
Dopo la parola chiave when c'è il codice che va eseguito se l'espressione del case corrisponde all'espressione del when.
Il case permette un'istruzione else facoltativa, che viene eseguita se nessun altro caso corrisponde.
L'espressione del case viene valutata e poi confrontata con ciascuna espressione del when.
Il confronto avviene tramite l'operatore di sussunzione del case (===).
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
===)L'operatore di sussunzione del case (===) è un po' diverso dall'operatore di uguaglianza (==).
L'operatore verifica se il lato destro è un membro dell'insieme descritto dal lato sinistro.
Questo significa che l'ordine in cui si trovano gli operandi è importante.
Come funziona dipende dal tipo del lato sinistro: per esempio, un Range verifica se il lato destro è nell'intervallo, mentre un Object verifica se il lato destro è un'istanza di Object.
(1..3) == 1 # => false
(1..3) === 1 # => true
String == "foo" # => false
String === "foo" # => true
I case permettono di far corrispondere più espressioni in un unico caso, separando ogni possibile valore con una virgola. Il codice viene eseguito se una qualsiasi delle espressioni corrisponde. Può essere utile per un singolo caso con più valori possibili.
case 1
when 1, 2
puts "One or two"
else
puts "Other"
end
I case possono anche verificare se un valore è compreso in un intervallo. Per farlo, si usa un intervallo come espressione del when.
case var
when 1..3
puts "One to three"
else
puts "Other"
end
Quando non serve un'espressione del case, è possibile ometterla. In questo modo, ogni espressione del caso viene valutata in base al suo valore di verità. E le fa comportare come istruzioni if-else-if.
case
when 1 == 1
puts "One is equal to one"
when 1 > 2
puts "One is greater than two"
else
puts "Other"
end
Crystal permette istruzioni case su una sola riga.
Si può usare quando si ha un'istruzione semplice su una sola riga.
L'istruzione when su una sola riga si scrive come when <expression> then <statement>.
E quando si usa nell'istruzione else, si scrive come else <statement>.
case var
when 1 then puts "One"
when 2 then puts "Two"
else puts "Other"
end
Il case permette di far corrispondere i tipi.
Il confronto usa l'operatore is_a? per verificare il tipo della variabile.
Per esempio, questo permette di avere un ramo per ogni tipo di un tipo unione.
case var
when Int32
puts "Int32"
when String
puts "String"
else
puts "Other"
end
Il case permette di usare un oggetto implicito. Questo permette, per esempio, che un'espressione del when sia una chiamata a un metodo sull'espressione del case. A seconda che il metodo restituisca un valore vero o falso, il caso corrisponderà oppure no.
case 1
when .odd?
puts "Odd"
when .even?
puts "Even"
end
Il case permette di avere case esaustivi, il che significa che è possibile assicurarsi che tutti i valori possibili siano gestiti.
È simile all'istruzione when, ma con la parola chiave in al posto di when.
Quando un case è esaustivo, non supporta istruzioni when né else.
I case esaustivi si possono usare su Bools, sui tipi Union, su Enum e su Tuples.
Gli ultimi due saranno trattati nei concetti successivi.
I case esaustivi implicano che tutte le possibilità vengano gestite, altrimenti viene generato un errore di compilazione.
Gestire i tipi Union come case esaustivo è simile a un case non esaustivo.
var : (Int32 | String | Bool)
case var
in Int32
puts "Int32"
in String
puts "String"
in Bool
puts "Bool"
end
I Bools si possono gestire come un case esaustivo usando le parole chiave true e false.
var : Bool
case var
in true
puts "True"
in false
puts "False"
end