C, PHP, VB, .NET

Дневникът на Филип Петров


* Switch изрази

Публикувано на 19 декември 2019 в раздел ПИК3 Java.

В Java 12, а по-късно подобрено в Java 13, се появиха тестови "Switch изрази", които се очаква да станат официална част от версия 14. Досега Switch беше само оператор. Вече може да бъде използван и като израз, който връща стойност. Например ако имаме следното решение за превръщане на число в текстовият низ за ден от седмицата:

int day = 5;
String dayStr;
switch(day){
  case 1: dayStr = "Понеделник";
          break;
  case 2: dayStr = "Вторник";
          break;
  case 3: dayStr = "Сряда";
          break;
  case 4: dayStr = "Четвъртък";
          break;
  case 5: dayStr = "Петък";
          break;
  case 6: dayStr = "Събота";
          break;
  case 7: dayStr = "Неделя";
          break;
  default: throw new IllegalArgumentException("Невалиден ден");
}

Вече може да бъде записано по следния начин:

int day = 5;
String dayStr = switch(day){
  case 1: yield "Понеделник";
  case 2: yield "Вторник";
  case 3: yield "Сряда";
  case 4: yield "Четвъртък";
  case 5: yield "Петък";
  case 6: yield "Събота";
  case 7: yield "Неделя";
  default: throw new IllegalArgumentException("Невалиден ден");
}

Освен, че кодът стана по-компактен, стана ненужно да се слага и досадният break. Новият оператор yield върши двойна работа - реално прекратява хода на switch оператора (прави break) и връща резултат от него (който в случая присвояваме на dayStr).

Още повече - може да използвате и "ламбда-подобен синтаксис". Горният пример ще е еквивалентен на:

int day = 5;
String dayStr = switch(day){
  case 1 -> "Понеделник";
  case 2 -> "Вторник";
  case 3 -> "Сряда";
  case 4 -> "Четвъртък";
  case 5 -> "Петък";
  case 6 -> "Събота";
  case 7 -> "Неделя";
  default -> throw new IllegalArgumentException("Невалиден ден");
}

При този синтаксис е възможно да създавате и блокове. Например:

String dayType = switch(x){
  case 1,2,3,4 -> "Работен ден";
  case 6,7 -> "Почивен ден";
  case 5 -> {
         System.out.println("Тихо! Скоро ще почиваме!");
         yield "Ден на майстора!";
  }
  default -> throw new IllegalArgumentException("Невалиден ден");
}

Важно е да се отбележи, че имаме следните ограничения при употребата на switch като израз:

  1. Всички случаи (case) трябва да имат yield, т.е. да връщат резултат;
  2. Наличието на default е задължително, с изключение на единствен случай - ако използваме enum и сме покрили всички възможни стойности на подадената променлива. При switch оператор не е задължително да покрием всички възможни стойности на тестваната променлива, но при switch израз е задължително да бъде така - именно затова винаги трябва да има default клауза включително когато сме напълно убедени, че до нея никога не може да се достигне;
  3. Не може да се използва оператор return (само при израз - ако switch е като оператор, няма проблем).

Забелязахте ли още нещо от по-горните примери? Да, в switch вече може да имаме case с повече от една стойност! Преди правихме следното:

switch(x){
  case 1:
  case 2: doStuffFor1and2();
          break;
  ...
}

а сега вече е възможно да го правим като:

switch(x){
  case 1,2: doStuffFor1and2();
            break;
  ...
}

 



Добави коментар

Адресът на електронната поща няма да се публикува


*