Try … catch … finally return value

后端 未结 4 1689
心在旅途
心在旅途 2021-02-07 01:24

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 = {
            


        
4条回答
  •  旧巷少年郎
    2021-02-07 02:03

    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.

提交回复
热议问题