I found that it\'s a shame that I can\'t return a return value from a such simple construction as try ... catch ... finally
def foo: String = {
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).
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()
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.
You can address this by having the catch block evaluate to a String as well:
catch {
case e: IOException => {
e.printStackTrace()
e.toString()
}
}
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() returns Unit, but that's ok because the value of the finally block is ignored. The try and catch blocks both return String.