Привет!
Во многих языках программирования есть конструкции управления выполнением кода - 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.
Комментариев нет:
Отправить комментарий