Try ... catch ... 最后返回值 [英] Try ... catch ... finally return value

查看:31
本文介绍了Try ... catch ... 最后返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现我不能从像 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.但是,无论哪种情况,trycatch 块的值都必须与函数签名匹配.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 块的值被忽略.trycatch 块都返回字符串.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆