Scala最终阻止关闭/刷新资源 [英] Scala finally block closing/flushing resource

查看:50
本文介绍了Scala最终阻止关闭/刷新资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有更好的方法来确保正确释放资源 - 编写以下代码的更好方法?

Is there a better way to ensure resources are properly released - a better way to write the following code ?

        val out: Option[FileOutputStream] = try {
          Option(new FileOutputStream(path))
        } catch {
          case _ => None
        }


        if (out.isDefined) {

          try {
            Iterator.continually(in.read).takeWhile(-1 != _).foreach(out.get.write)
          } catch {
            case e => println(e.getMessage)
          } finally {
            in.close
            out.get.flush()
            out.get.close()
          }

        }

推荐答案

这样的想法是个好主意,但我会把它变成一种方法:

Something like that is a good idea, but I'd make it a method:

def cleanly[A,B](resource: => A)(cleanup: A => Unit)(code: A => B): Option[B] = {
  try {
    val r = resource
    try { Some(code(r)) }
    finally { cleanup(r) }
  } catch {
    case e: Exception => None
  }
}

(请注意,我们只捕获一次;如果您确实希望在一种情况下而不是另一种情况下打印消息,那么您必须像以前一样同时捕获两者).(另请注意,我只捕获异常;捕获 Error 通常也是不明智的,因为几乎不可能从中恢复.)该方法的使用如下:

(note that we only catch once; if you really want a message printed in one case and not the other, then you do have to catch both like you did). (Also note that I only catch exceptions; catching Error also is usually unwise, since it's almost impossible to recover from.) The method is used like so:

cleanly(new FileOutputStream(path))(_.close){ fos =>
  Iterator.continually(in.read).takeWhile(_ != -1).foreach(fos.write)
}

因为它返回一个值,如果在这里成功,你会得到一个 Some(())(你可以忽略).

Since it returns a value, you'll get a Some(()) if it succeeded here (which you can ignore).

为了使它更通用,我真的让它返回一个 Either 代替,所以你会得到异常.像这样:

to make it more general, I'd really have it return an Either instead, so you get the exception. Like so:

def cleanly[A,B](resource: => A)(cleanup: A => Unit)(code: A => B): Either[Exception,B] = {
  try {
    val r = resource
    try { Right(code(r)) } finally { cleanup(r) }
  }
  catch { case e: Exception => Left(e) }
}

现在,如果您获得了 Right,一切都会顺利.如果你得到一个 Left,你可以选择你的例外.如果你不关心异常,你可以使用 .right.toOption 将它映射到一个选项,或者只使用 .right.map 或任何操作只有当它存在时才能得到正确的结果(就像 Option 一样).(模式匹配是处理 Either 的有用方法.)

Now if you get a Right, all went okay. If you get a Left, you can pick out your exception. If you don't care about the exception, you can use .right.toOption to map it into an option, or just use .right.map or whatever to operate on the correct result only if it is there (just like with Option). (Pattern matching is a useful way to deal with Eithers.)

这篇关于Scala最终阻止关闭/刷新资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆