Scala 如何从功能上处理IO

Scala 如何从功能上处理IO,scala,Scala,我有以下代码,我不想使用var SysProc,有没有一种功能性的方法可以做到这一点 var proc: SysProc = null try { proc = SysProc(scalaTestCommand).run(ProcessLogger(out.append, out.append)) forkProcess(proc, Settings.scalaTestTimeout) } catch { case e: TimeoutE

我有以下代码,我不想使用var SysProc,有没有一种功能性的方法可以做到这一点

   var proc: SysProc = null
    try {
      proc = SysProc(scalaTestCommand).run(ProcessLogger(out.append, out.append))
      forkProcess(proc, Settings.scalaTestTimeout)
    } catch {
      case e: TimeoutException =>
        val msg = "Timeout when running ScalaTest\n" + out.toString()
        logError(msg)
        proc.destroy()
        sys.error(msg)
      case e: Throwable =>
        val msg = "Error occurred while running the ScalaTest command\n" + e.toString + "\n" + out.toString()
        logError(msg)
        proc.destroy()
        throw e
    } finally {
      println(out.toString)
      if (proc != null) {
        println("Exit process: " + proc.exitValue())
      }
    }

从技术上讲,如果您的
SysProc
builder在构建过程中抛出,则不会设置var,因此您可以执行如下操作:

try {
  val proc = SysProc(scalaTestCommand).run(ProcessLogger(out.append, out.append))
  try {
    forkProcess(proc, Settings.scalaTestTimeout)
  } finally {
    proc.destroy()
    println("Exit process: " + proc.exitValue())
  }
} catch {
  case e: TimeoutException =>
    val msg = "Timeout when running ScalaTest\n" + out.toString()
    logError(msg)
    sys.error(msg)
  case e: Throwable =>
    val msg = "Error occurred while running the ScalaTest command\n" + e.toString + "\n" + out.toString()
    logError(msg)
    throw e
}
这已经是没有变量的代码了

如果你想更具功能性,你可以考虑诸如“代码>猫”、“效果”、“资源< /代码>和<代码>猫。

Resource {
  // how to acquire resource
  IO(SysProc(scalaTestCommand).run(ProcessLogger(out.append, out.append)))
} { proc =>
  // how release resource when it is not needed
  // - no matter if it was used successfuly or not
  IO {
    proc.destroy()
    println("Exit process: " + proc.exitValue())
  }
} // defines resource
 .use(forkProcess(_, Settings.scalaTestTimeout)) // create-use-release resource
 .handleErrorWith {
    case e: TimeoutException =>
      val msg = s"Timeout when running ScalaTest\n$out"
      IO(logError(msg)) >> IO(sys.error(msg))
  case e: Throwable =>
      val msg = s"Error occurred while running the ScalaTest command\n$e\n$out"
      IO(logError(msg)) >> IO.raiseError(e)
  } // handle errors if happened
  .unsafeRunSync // run computation (in this case synchronously)