Функциональный try & catch со Scala - PullRequest
21 голосов
/ 01 марта 2011

Существует ли более идиоматический способ открытия ресурса в Scala и применения к нему методов, чем этот метод (перевод непосредственно из Java):

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()
}

Ответы [ 4 ]

19 голосов
/ 01 марта 2011

Шаблон ссуды реализован различными способами в библиотеке 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 _ =>
}
13 голосов
/ 01 марта 2011

Используйте шаблон Loan (неработающая ссылка) непостоянная ссылка на новое местоположение .

5 голосов
/ 01 марта 2011

Это может быть один из случаев, когда нежелательно работать.Уже упомянутая схема заимствования является лишь инкапсуляцией беспристрастной версии обработки ошибок, но она не имеет ничего общего с функциональным программированием, а также не заботится об обработке ошибок.

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

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

0 голосов
/ 31 марта 2019

Начиная с Scala 2.13, стандартная библиотека предоставляет специальную утилиту управления ресурсами: Using.

В этом случае его можно использовать с FileInputStream, поскольку он реализует AutoCloseable, чтобы воспроизводить входной файл и, несмотря ни на что, закрывать ресурс файла. потом:

import scala.util.{Using, Failure}
import java.io.FileInputStream

Using(new FileInputStream(in)) {
  is => func(is)
}.recoverWith {
  case e: java.io.IOException =>
    println("Error: could not open file.")
    Failure(e)
}

Поскольку Using создает Try, обеспечивающий либо результат операции, либо ошибку, мы можем работать с исключением через Try#recoverWith.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...