首页 > 解决方案 > 尽量避免在我的方法中有两个 try 块

问题描述

如何避免if在我的代码中重复条件:

  def download() =
    Action {
      val out = new FileWriter("/tmp/foo.txt")
      Try {
        val chars = new Array[Char](1024)
        util.Arrays.fill(chars, '.')
        chars(1024) = '\n'
        out.write(chars)
      } match {
        case Failure(_) =>
          if (out != null) out.close()
          println("failed")
        case Success(_) =>
          if (out != null) out.close()
          println("success")
      }
    }

我试图从以下方面进行调整:

  def download() =
    Action {
      Try {
        val out = new FileWriter("/tmp/foo.txt")
        try{
        val chars = new Array[Char](1024)
        util.Arrays.fill(chars, '.')
        chars(1024) = '\n'
        out.write(chars)
        } if (out != null) out.close()
      } match {
        case Failure(_) =>
          println("failed")
        case Success(_) =>
          println("success")
      }
    }

但是这样我try在 Scala中就有了一个 Java Try,这看起来不正确。如何避免有两个 try 块?我基本上只是希望在方法完成执行后清理我获得的资源。

标签: scala

解决方案


如果您不能使用Using,您可以使用try-catch-finally

def download() =
  Action {
    val out = new FileWriter("/tmp/foo.txt")
    try {
      val chars = new Array[Char](1024)
      util.Arrays.fill(chars, '.')
      chars(1024) = '\n'
      out.write(chars)
      println("success")
    } catch {
      case _: Throwable =>
        println("failed")
    } finally {
      out.close()
    }
  }

或贷款模式:

def withFileWriter[A](str: String)(f: FileWriter => A): Try[A] = Try {
  val out = new FileWriter("/tmp/foo.txt")
  try {
    f(out)
  } finally {
    out.close()
  }
}

withFileWriter("/tmp/foo.txt"){ out =>
  util.Arrays.fill(chars, '.')
  chars(1024) = '\n'
  out.write(chars)
} match {
  case Failure(_) =>
    println("failed")
  case Success(_) =>
    println("success")
}

如果你有 Cats Effect(并且如果你用合法的东西替换 Try),你可以使用 Resource

val resource = Resource.make {
  IO(new FileWriter("/tmp/foo.txt"))
} { out =>
  IO(out.close())
}

resource.use(out => IO {
  util.Arrays.fill(chars, '.')
  chars(1024) = '\n'
  out.write(chars)
}).attempt.map {
  case Failure(_) =>
    println("failed")
  case Success(_) =>
    println("success")
}.unsafeRunSync

推荐阅读