【问题标题】:Functional try & catch with ScalaScala 的函数式 try & catch
【发布时间】:2011-07-06 03:52:34
【问题描述】:

有没有比这个方法更惯用的方式在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()
}

【问题讨论】:

标签: scala functional-programming


【解决方案1】:

贷款模式在 Josh Suereth 在 github 上的 scala-arm 库中以各种方式实现。

然后您可以使用这样的资源:

val result = managed(new FileInputStream(in)).map(func(_)).opt 

这将返回包裹在Option 中的func 的结果,并负责关闭输入流。

为了处理创建资源时可能出现的异常,可以结合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】:

    【讨论】:

    • Scala 标准库中是否有任何标准实现,或者我应该在 util 模块中自己制作?
    • @aharon 请参阅您的答案下方的评论——Josh Suereth 的 ARM 库可以做到这一点。
    • @WinMyoHtet:它现在在那里 wiki.scala-lang.org/display/SYGN/Loan 但现在,有说明他们不鼓励创建永久链接
    【解决方案3】:

    这可能是不希望发挥作用的一种情况。上面提到的贷款模式只是对错误处理的象征性版本的封装,与函数式编程无关,也没有处理错误处理。

    如果您真的希望它具有功能性,您可以使用error handling monad 来实现。出于充分的理由,我提供的链接是针对此的 Haskell 特定文档,因为 Scala 不太支持这种“核心”功能实践。

    我建议您采用命令式的方式并最终使用 try catch...您还可以使用错误处理扩展贷款模式,但这意味着如果您想在某些情况下以不同的方式处理错误,则必须编写特殊函数情况,否则您将不得不传递部分函数以进行错误处理(这只不过是您在代码中的 catch 块中已经获得的内容)。

    【讨论】:

    【解决方案4】:

    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 处理异常。

    【讨论】:

      猜你喜欢
      • 2012-04-24
      • 2017-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-14
      • 2021-11-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多