如何表达 Scala 的 Try 的 *finally* 等价物? [英] How can I express *finally* equivalent for a Scala's Try?

查看:34
本文介绍了如何表达 Scala 的 Try 的 *finally* 等价物?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用新的 Try API 将以下 Java 代码转换为 Scala?

How do I translate the following Java code to Scala using the new Try API?

public byte[] deflate(byte[] data) {

    ByteArrayOutputStream outputStream = null;
    GZIPOutputStream gzipOutputStream = null;

    try {
        outputStream = new ByteArrayOutputStream();
        gzipOutputStream = new GZIPOutputStream(outputStream);
        gzipOutputStream.write(data);
        return outputStream.toByteArray();
    catch (Exception e) {
        ...
    } finally {
        if (gzipOutputStream != null) gzipOutputStream.close();
    }
}

Scala 版本应该是这样的...

The Scala version should be something like this...

def deflate(data Array[Byte]): Try[Array[Byte]] = Try {
  ByteArrayOutputStream outputStream = new ByteArrayOutputStream()
  new GZIPOutputStream(outputStream).write(data)
  outputStream.toByteArray
}

...但是我如何实现 Java 的 finally 等价物?

... but how do I implement Java's finally equivalent?

推荐答案

由于 Try {} 块永远不会抛出异常,因此不需要 finally 语句.此外,对于这种特殊情况,您可能应该使用 scala-arm,就像其他海报建议的那样.

Since a Try {} block will never throw an exception, there is no need for a finally statement. Also, for this particular scenario you should probably use scala-arm, like other posters have suggested.

但是您可以轻松地向 Try 添加一个 finally 方法,该方法在成功或失败的情况下都会产生副作用.

But you can easily add a finally method to a Try that performs a side-effect in case of either success or failure.

像这样:

implicit class TryHasFinally[T](val value:Try[T]) extends AnyVal { 
  import scala.util.control.NonFatal

  def Finally(action: => Unit) : Try[T] = 
    try { 
      action; 
      value 
    } catch { 
      case NonFatal(cause) => Failure[T](cause)
    } 
}

请注意,本着 Try 的所有方法的精神,如果您的操作抛出非致命异常,则不会抛出异常,而只是将其捕获为失败.

Note that in the spirit of all methods of Try, this will not throw an exception if your action throws a non-fatal exception, but simply capture it as a Failure.

你会像这样使用它:

import java.io._
import java.util.zip._

def deflate(data: Array[Byte]): Try[Array[Byte]] = {
  var outputStream : ByteArrayOutputStream = null
  Try {
    outputStream = new ByteArrayOutputStream()
    new GZIPOutputStream(outputStream).write(data)
    outputStream.toByteArray
  } Finally {
    outputStream.close()
  }
}

请注意,您不必在Finally 中检查null,因为如果由于某些深不可测的原因输出流为null,您将只会得到一个Failure(NullPointerException).此外,如果 close 抛出 IOException,您只会得到一个 Failure(IOException).

Note that you don't have to check for null in the Finally, since if for some unfathomable reason the outputStream is null you will just get a Failure(NullPointerException). Also, in the event that close throws an IOException you will just get a Failure(IOException).

这篇关于如何表达 Scala 的 Try 的 *finally* 等价物?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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