Подтвердить что ты не робот

Функциональный 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()
}
4b9b3361

Ответ 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 _ =>
}

Ответ 3

Это может быть один случай, когда нежелательно функционировать. Все уже упомянутая модель кредита - это всего лишь инкапсуляция нестандартной версии обработки ошибок, но это не имеет никакого отношения к функциональному программированию, а также doenst заботится об обработке ошибок.

Если вы действительно хотели его функционировать, вы могли бы сделать это с помощью ошибки обработки монады. По уважительной причине ссылка, которую я предоставляю, представляет собой специальную документацию Haskell к этому, так как Scala не поддерживает такую ​​ "хардкорную" функциональную практику так хорошо.

Я бы рекомендовал вам перейти к императивному способу и, наконец, использовать try catch... вы также можете расширить шаблон кредита с помощью обработки ошибок, но это означает, что вам нужно либо писать специальные функции, если вы хотите обрабатывать ошибки по-разному в некоторых или вам придется передать частичную функцию для обработки ошибок (что не что иное, как то, что вы уже получили внутри блока catch в вашем коде).