Привет!
Во многих языках программирования есть конструкции управления выполнением кода - for, while, if etc.
Где-то их больше, где-то -- меньше. Они составляют базис языка.
Scala -- не исключение и тоже содержит некоторое число встроенных управляющих конструкций (напр. if, for) но в ней возможно написать нечто свое очень похожее внешне на "control structure".
Т.е. выглядящее вот так:
С виду очень похожее на "встроенную" возможность языка, но breakable входит в scala-library.jar как простая фунция.
Тем, кому не хватало какой-нибудь экзотической конструкции могут написать ее сами.
Во многих языках программирования есть конструкции управления выполнением кода - for, while, if etc.
Где-то их больше, где-то -- меньше. Они составляют базис языка.
Scala -- не исключение и тоже содержит некоторое число встроенных управляющих конструкций (напр. if, for) но в ней возможно написать нечто свое очень похожее внешне на "control structure".
Т.е. выглядящее вот так:
breakable { // your code is here if (someCondition) { break } }
С виду очень похожее на "встроенную" возможность языка, но breakable входит в scala-library.jar как простая фунция.
Тем, кому не хватало какой-нибудь экзотической конструкции могут написать ее сами.
Пример ниже:
type Resource = BufferedReader type ResourceUsage = (Resource => Any) def use(closable: => Resource)(code: => ResourceUsage) { /** * Function in function. Comfortable isn't it? */ def handleEx(e: IOException) { sys.error(e.getStackTraceString) } try { val resourceToClose = closable // use opened resource code(resourceToClose) resourceToClose.close() } catch { case e: IOException => { handleEx(e) } } }
Эта структура, названная use избавляет нас от необходимости писать try-catch при использовании файла.
К тому же она сама закроет reader в конце работы с ним.
Так называемый call-by-name приводит к тому, что выражение:
Так называемый call-by-name приводит к тому, что выражение:
new BufferedReader(new FileReader(new File("c:\\tmp\\1.txt")))
вызывается внутри ф-и, а не до вызова use. В Java для подобного нужно было бы
делать некий callback интерфейс, который нужно было бы "дёргать" из функции use() вызывая
нужный блок кода "потом".
А поскольку блок val resourceToClose = closable находится в тесном окружении блока try-catch внутри функции, то и беспокоиться за "вылет" исключения при вызове use() не нужно. Все будет обработано внутри def use().
Ф-я use() "каррированная" -- возвращает ф-ю, которая использует параметр переданный в порождающию функцию use(). Это дает возможность передать второй параметр (блок кода, который работает с открытым ридером) не в скобках, а используя "{}".
Ф-я use() "каррированная" -- возвращает ф-ю, которая использует параметр переданный в порождающию функцию use(). Это дает возможность передать второй параметр (блок кода, который работает с открытым ридером) не в скобках, а используя "{}".
Что делает use() ничем не отличающейся с виду от того же "while() {}".
Кстати, def handleEx(e: IOException) находится внутри ф-и use(...) что очень удобно с точки зрения логической группировки кода (к подобному удобству привыкли те, кто достаточно поработал с Javascript).
Кстати, def handleEx(e: IOException) находится внутри ф-и use(...) что очень удобно с точки зрения логической группировки кода (к подобному удобству привыкли те, кто достаточно поработал с Javascript).
Итог
Количество "своих" управляющих конструкций ограниченно разве что необходимостью в проекте и желанием автора.
Возможность несомненно понравится тем, кто мигрирует с других языков и кто имеет набор понравившихся функций которые есть там, но которых не хватает в Scala.
Комментариев нет:
Отправить комментарий