try / catch / finally是scala中的表达式吗?如果是,最终如何以及何时执行?

时间:2019-01-26 14:38:40

标签: scala

我写了一些代码,对此我感到有些惊讶。我专门使用try / catch / finally只是为了了解它如何在scala中工作。

我很惊讶,但似乎try / catch / finally实际上是scala中的一种表达?是新的还是我错过了什么?从某种程度上讲,我可以理解它的功能,但是这些都是语言中的关键字,我看不到定义它们的功能。

在该代码中,我也无法理解为什么最终不对返回类型有所贡献。只有catch and try确实有助于返回类型。因此,我不确定何时确切执行。

有人可以向我解释或指出该声明的规范,以便我理解。再次,我知道使用Try类型是定义方法,但我只想了解这里发生的情况。

def createTripleList(msg: String): List[String] = {

  val outStream = new ByteArrayOutputStream

  try {
    val model = ModelFactory.createDefaultModel()
    val jld = model.read(new ByteArrayInputStream(msg.getBytes()), null, "JSON-LD")
    jld.write(outStream, "N-TRIPLE", null)
    model.close()
    outStream.toString.split("\n").toList
  }
  catch {
    case e:Throwable => println(s"Could not parse JsonLd: ${e.toString}"); List.empty[String]
  }
  finally {outStream.close()}
}

1 个答案:

答案 0 :(得分:3)

来自 Scala语言规范

  

“ try表达式的形式为try {b} catch h”。

     

“让pt为try表达式的预期类型。块b与pt一致。处理程序h与scala.PartialFunction [scala.Throwable,pt]类型兼容。try表达式的类型是b类型和h类型的结果类型的最弱最小上限。

     

“一个try表达式try {b}最终e对块b求值。如果对b的求值没有引发异常,则对表达式e求值。如果对e求值时抛出异常,则对e的求值try表达式因抛出的异常而中止。如果在e的求值过程中未抛出异常,则将b的结果作为try表达式的结果返回。”

     

“如果在b的求值过程中引发了异常,则也对e块进行求值。如果在e的求值过程中引发了另一个异常e,则try表达式的求值将被抛出的异常中止。在评估e的过程中,一旦e的评估完成,则抛出在b中引发的原始异常。块b期望符合try表达式的预期类型。最终表达式e应当符合Unit的类型。

     

-Source

TL; DR

无论发生什么情况,总是执行 finally块,并且它的类型应为Unit-这意味着它不会影响表达式的返回类型。
但是,try / catch的返回类型是 try块 b的返回类型和返回的“最小最小上限” 异常处理程序的类型 h