case (часто його називають switch в інших мовах), як і if-else, належить до керуючих виразів.
case дає змогу обʼєднувати в ланцюжок кілька інструкцій if-else-if, читається краще й дозволяє створювати потужні конструкції.
Конструкція case задається ключовим словом case, після якого йде необовʼязковий вираз.
Далі для кожного випадку використовується ключове слово when, після якого йде вираз, що порівнюється з виразом case.
Ключове слово when не повинно мати відступу відносно ключового слова case.
Після ключового слова when іде код, який має виконатися, якщо вираз case збігається з виразом when.
case дозволяє додати необовʼязкову інструкцію else, яка виконується, якщо жоден інший випадок не збігається.
Вираз case обчислюється, а потім порівнюється з кожним виразом when.
Порівняння виконується за допомогою оператора включення (===).
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
===)Оператор включення (===) трохи відрізняється від оператора рівності (==).
Оператор перевіряє, чи права частина належить множині, описаній лівою частиною.
Це означає, що порядок операндів має значення.
Те, як це працює, залежить від типу лівої частини: наприклад, Range перевірить, чи права частина належить діапазону, а Object перевірить, чи права частина є екземпляром Object.
(1..3) == 1 # => false
(1..3) === 1 # => true
String == "foo" # => false
String === "foo" # => true
case дозволяє зіставити кілька виразів в одному випадку, розділяючи кожне можливе значення комою.
Код виконається, якщо збігається будь-який з виразів.
Це буває корисно, коли один випадок має кілька можливих значень.
case 1
when 1, 2
puts "One or two"
else
puts "Other"
end
case також може перевірити, чи значення належить діапазону.
Для цього діапазон використовують як вираз when.
case var
when 1..3
puts "One to three"
else
puts "Other"
end
case
Коли вираз case не потрібен, його можна опустити.
Тоді кожен вираз перевіряється на правдивість.
І вони поводяться як інструкції 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
when
Crystal дозволяє записувати конструкцію case в один рядок.
Це зручно, коли інструкція проста й уміщається в один рядок.
Однорядковий when записують так: when <expression> then <statement>.
А в гілці else це записують як else <statement>.
case var
when 1 then puts "One"
when 2 then puts "Two"
else puts "Other"
end
case дозволяє зіставляти значення з типами.
Порівняння використовує оператор is_a?, щоб перевірити тип змінної.
Наприклад, це дозволяє мати окрему гілку для кожного типу в обʼєднаному типі.
case var
when Int32
puts "Int32"
when String
puts "String"
else
puts "Other"
end
case дозволяє використовувати неявний обʼєкт.
Завдяки цьому вираз when може бути, наприклад, викликом методу на виразі case.
Залежно від того, чи повертає метод правдиве значення, чи неправдиве, випадок збігається або ні.
case 1
when .odd?
puts "Odd"
when .even?
puts "Even"
end
case
case може бути вичерпним: це дає змогу гарантувати, що оброблено всі можливі значення.
Він схожий на конструкцію when, але замість when використовується ключове слово in.
Якщо case вичерпний, він не підтримує жодних гілок when чи else.
Вичерпний case можна застосовувати до Bools, типів Union, Enum і Tuples.
Про два останні йтиметься в наступних концепціях.
Вичерпність означає, що потрібно обробити всі можливості, інакше виникне помилка компіляції.
Обробка типів Union вичерпним case схожа на невичерпний case.
var : (Int32 | String | Bool)
case var
in Int32
puts "Int32"
in String
puts "String"
in Bool
puts "Bool"
end
Bools можна обробити вичерпним case, використавши ключові слова true і false.
var : Bool
case var
in true
puts "True"
in false
puts "False"
end