Функциональный try & catch w/Scala
Есть ли более идоматический способ открытия ресурса в Scala и применения к нему методов, чем этот метод (транслируется непосредственно из java), используя vals
, но также включая окончание и т.д.
var is:FileInputStream = null
try {
is = new FileInputStream(in)
func(is)
} catch {
case e:IOException =>
println("Error: could not open file.")
println(" -> " + e)
exit(1)
} finally {
if(is) is.close()
}
Ответы
Ответ 1
Шаблон кредита реализован по-разному в библиотеке Josh Suereth scala-arm на github.
Затем вы можете использовать ресурс, подобный этому:
val result = managed(new FileInputStream(in)).map(func(_)).opt
который вернет результат func
, завернутый в Option
, и позаботится о закрытии входного потока.
Чтобы справиться с возможными исключениями при создании ресурса, вы можете объединить с объектом scala.util.control.Exception
:
import resource._
import util.control.Exception.allCatch
allCatch either {
managed(new FileInputStream(in)).map(func(_)).opt
} match {
case Left(exception) => println(exception)
case Right(Some(result)) => println(result)
case _ =>
}
Ответ 2
Используйте шаблон займа (мертвая ссылка) не постоянная ссылка на новую место.
Ответ 3
Это может быть один случай, когда нежелательно функционировать. Все уже упомянутая модель кредита - это всего лишь инкапсуляция нестандартной версии обработки ошибок, но это не имеет никакого отношения к функциональному программированию, а также doenst заботится об обработке ошибок.
Если вы действительно хотели его функционировать, вы могли бы сделать это с помощью ошибки обработки монады. По уважительной причине ссылка, которую я предоставляю, представляет собой специальную документацию Haskell к этому, так как Scala не поддерживает такую "хардкорную" функциональную практику так хорошо.
Я бы рекомендовал вам перейти к императивному способу и, наконец, использовать try catch... вы также можете расширить шаблон кредита с помощью обработки ошибок, но это означает, что вам нужно либо писать специальные функции, если вы хотите обрабатывать ошибки по-разному в некоторых или вам придется передать частичную функцию для обработки ошибок (что не что иное, как то, что вы уже получили внутри блока catch в вашем коде).