Try ... catch ... 最后返回值 [英] Try ... catch ... finally return value
问题描述
我发现我不能从像 try ... catch ... finally
def foo: String = {
val in = new BufferedReader(.....)
try {
// val in = new BufferedReader(.....) -- doesn't matter
in.readLine
}
catch {
case e: IOException => e.printStackTrace()
}
finally {
in.close()
}
}
此代码无法编译.有什么方法可以使用任何库、高级结构等使编译 expect ?我只想通过使用纯 Scala 作为编程语言的能力来做到这一点.
This code doesn't compile. Is there any way to make compile expect using any libraries, high-level constructions, etc? I want to do that only by using the capacity of pure Scala as a programming language.
推荐答案
在 Scala 的 try-catch-finally 块中,finally
块被评估 only 的副作用;整个块的值是 try
(如果没有抛出异常)或 catch
(如果有)中最后一个表达式的值.
In a scala try-catch-finally block, the finally
block is evaluated only for side effects; the value of the block as a whole is the value of the last expression in the try
(if no exception was thrown) or catch
(if one was).
如果您查看编译器的输出,您会注意到它在抱怨 catch
块的内容,而不是 finally
:
If you look at the output from the compiler, you'll note that it's complaining about the contents of the catch
block, not the finally
:
$ scala test.scala
/tmp/test.scala:12: error: type mismatch;
found : Unit
required: String
case e: Exception => e.printStackTrace()
这是因为Exception.printStackTrace()
返回Unit
,所以函数的返回类型必须是String
,如果try
成功,Unit
否则.
This is because Exception.printStackTrace()
returns Unit
, so the return type of the function would have to be String
if the try
succeeded and Unit
otherwise.
您可以通过将 catch
块也计算为字符串来解决这个问题:
You can address this by having the catch
block evaluate to a String as well:
catch {
case e: IOException => {
e.printStackTrace()
e.toString()
}
}
当然,这意味着即使发生错误,也必须有一些有用的字符串值可以返回(也许是""
?);更惯用的方法可能是返回一个 Option[String]
,try
块返回 Some(in.readLine)
和 catch
块返回 None
.但是,无论哪种情况,try
和 catch
块的值都必须与函数签名匹配.finally
块的类型无关紧要.
Of course, this means there has to be some useful string value you can return even when an error occurs (perhaps ""
?); a more idiomatic approach might be to return an Option[String]
, with the try
block returning Some(in.readLine)
and the catch
block returning None
. In either case, though, the value of both the try
and catch
blocks must match the function signature. The finally
block's type is irrelevant.
作为参考,这是一个通过类型检查并有效的版本:
For reference, here's a version that passes type checking and works:
import java.io.BufferedReader
import java.io.InputStreamReader
import java.io.IOException
def foo: String = {
val in = new BufferedReader(new InputStreamReader(System.in))
try {
in.readLine
}
catch {
case e: IOException => { e.printStackTrace(); e.toString() }
}
finally {
in.close()
}
}
System.out.println("Return value: " + foo)
in.close()
返回 Unit,但这没关系,因为 finally
块的值被忽略.try
和 catch
块都返回字符串.
in.close()
returns Unit, but that's ok because the value of the finally
block is ignored. The try
and catch
blocks both return String.
这篇关于Try ... catch ... 最后返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!