Parcours
/
Crystal
Crystal
/
Programme
/
Instruction `case`
In

Instruction `case` en Crystal

1 exercice

À propos de Instruction `case`

case (souvent appelé switch dans d'autres langages) est une forme d'expression de contrôle, comme les instructions if et else. case permet d'enchaîner plusieurs instructions if/elsif, ce qui peut être plus lisible, et ouvre la porte à des constructions puissantes.

Un case est défini par le mot-clé case, suivi d'une expression facultative. Ensuite, pour chaque cas, on utilise le mot-clé when, suivi d'une expression qui est comparée à l'expression du case. Le mot-clé when ne doit pas être indenté par rapport au mot-clé case. Après le mot-clé when vient le code à exécuter si l'expression du case correspond à celle du when. Un case accepte une instruction else facultative, qui est exécutée si aucune autre branche ne correspond.

L'expression du case est évaluée, puis comparée à chaque expression du when. La comparaison utilise l'opérateur de subsomption de 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'opérateur de subsomption de case (===)

L'opérateur de subsomption de case (===) est un peu différent de l'opérateur d'égalité (==). Cet opérateur vérifie si l'opérande de droite est un membre de l'ensemble décrit par l'opérande de gauche. Cela signifie que l'ordre des opérandes a son importance. Le fonctionnement dépend du type de l'opérande de gauche : par exemple, un Range vérifie si l'opérande de droite se trouve dans l'intervalle, tandis qu'un Object vérifie si l'opérande de droite est une instance de cet Object.

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

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

Un case avec plusieurs expressions

Un case permet de faire correspondre plusieurs expressions dans une même branche, chaque valeur possible étant séparée par une virgule. Le code est exécuté si l'une des expressions correspond. C'est utile lorsqu'un même cas admet plusieurs valeurs possibles.

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

Un case avec des intervalles

Un case peut aussi vérifier qu'une valeur se trouve dans un intervalle. Il suffit pour cela d'utiliser un intervalle comme expression du when.

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

Un case sans expression

Quand aucune expression n'est nécessaire, on peut l'omettre. Chaque expression du when est alors évaluée comme vraie ou fausse. Ce qui les fait se comporter comme des instructions if/elsif.

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

Le when sur une seule ligne

Crystal permet d'écrire des case sur une seule ligne. On peut y recourir lorsqu'on a une instruction simple qui tient sur une seule ligne. La branche when sur une seule ligne s'écrit when <expression> then <statement>. Et dans une instruction else, elle s'écrit else <statement>.

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

Un case avec des types

Un case permet de faire correspondre des types. La comparaison utilise l'opérateur is_a? pour vérifier le type de la variable. Cela permet par exemple d'avoir une branche pour chaque type d'un type union.

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

L'objet implicite

Un case permet d'utiliser un objet implicite. Cela permet par exemple qu'une expression du when soit un appel de méthode sur l'expression du case. Selon que la méthode renvoie une valeur vraie ou fausse, la branche est retenue ou non.

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

Le case exhaustif

Un case peut être exhaustif, ce qui permet de garantir que toutes les valeurs possibles sont traitées. C'est semblable à l'instruction when, mais avec le mot-clé in à la place de when. Quand un case est exhaustif, il n'accepte aucune instruction when ni else.

Le case exhaustif peut s'utiliser avec Bools, les types Union, Enum et Tuples. Les deux derniers seront abordés dans des concepts ultérieurs.

Un case exhaustif impose que toutes les possibilités soient traitées, sans quoi une erreur de compilation est levée. Traiter les types Union avec un case exhaustif est semblable à un case non exhaustif.

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

On peut traiter Bools avec un case exhaustif en utilisant les mots-clés true et false.

var : Bool
case var
in true
  puts "True"
in false
  puts "False"
end
Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet

Apprends Instruction `case`

L'entraînement est verrouillé

Déverrouille 6 exercices de plus pour t'entraîner sur Instruction `case`