Scala 从Catch返回值

Scala 从Catch返回值,scala,try-catch,Scala,Try Catch,我的应用程序从文件中读取一些配置值。如果过程中有任何错误,我想为这些配置参数设置默认值。我正在做的是: val (param1, param2) = { try{ val props = new java.util.Properties props.load(getClass.getResource("/myapp.properties").openStream) ( props.getProperty("param1", "default1"),

我的应用程序从文件中读取一些配置值。如果过程中有任何错误,我想为这些配置参数设置默认值。我正在做的是:

val (param1, param2) = {
  try{
    val props = new java.util.Properties
    props.load(getClass.getResource("/myapp.properties").openStream)
    (
      props.getProperty("param1", "default1"),
      props.getProperty("param2", "default2")
    )
  }
  catch{
    case _ => ("default1", "default2")
  }
}

我知道,如果出现异常,我在catch块中执行的操作将无法按预期工作。有办法解决吗?我正在使用Scala 2.9,这将起作用,但它可能会导致运行时错误,因为

val (a,b) = whatever
只要
无论什么
Tuple2
的超类型,就可以调用它——特别是,它可以是
AnyRef
Any
,如果类型足够不匹配,try/catch返回值确实会扩大到这一点。您可以通过添加类型归属来确保它是正确的类型:

val (a,b): (A, B) = whatever
然后,如果在try/catch的整个过程中,右侧的类型都不正确,则类型检查器将进行投诉

例如:

val (a,b): (String, String) = try {
  ("perch", if (scala.util.Random.nextBoolean) throw new Exception else "halibut")
} catch {
  case e: Exception => ("salmon", "herring")
}
如果试图在
“herring”
之后添加
,“cod”
,则会出现编译时错误。如果重复输入此作业,将给您a=鲈鱼和b=大比目鱼一半时间,a=鲑鱼和b=鲱鱼另一半时间


附录:在2.9(或以下,我想,尽管我没有检查),您必须在try/catch语句中添加类型归属,如下所示:

val (a,b) = (try {
  ("perch", if (scala.util.Random.nextBoolean) throw new Exception else "halibut")
} catch {
  case e: Exception => ("salmon", "herring")
}): (String, String)

获取捕获的类型检查。

这将起作用,但它可能会导致运行时错误,因为

val (a,b) = whatever
只要
无论什么
Tuple2
的超类型,就可以调用它——特别是,它可以是
AnyRef
Any
,如果类型足够不匹配,try/catch返回值确实会扩大到这一点。您可以通过添加类型归属来确保它是正确的类型:

val (a,b): (A, B) = whatever
然后,如果在try/catch的整个过程中,右侧的类型都不正确,则类型检查器将进行投诉

例如:

val (a,b): (String, String) = try {
  ("perch", if (scala.util.Random.nextBoolean) throw new Exception else "halibut")
} catch {
  case e: Exception => ("salmon", "herring")
}
如果试图在
“herring”
之后添加
,“cod”
,则会出现编译时错误。如果重复输入此作业,将给您a=鲈鱼和b=大比目鱼一半时间,a=鲑鱼和b=鲱鱼另一半时间


附录:在2.9(或以下,我想,尽管我没有检查),您必须在try/catch语句中添加类型归属,如下所示:

val (a,b) = (try {
  ("perch", if (scala.util.Random.nextBoolean) throw new Exception else "halibut")
} catch {
  case e: Exception => ("salmon", "herring")
}): (String, String)


获取渔获物的类型检查。

为什么您认为这不会如预期的那样起作用?您可能希望捕获的内容不那么杂乱无章,但除此之外,它看起来是可行的,即使不是惯用的scala。@不明确:我已尝试将其更改为
case=>(“def1”、“def2”、“junk”)
,编译器没有抱怨,我将其解释为结果可能被忽略的迹象。而且,大多数情况下,一个人写的东西返回
单元
(比如打印错误消息等)。编译器如何知道何时要使用结果?编译器推断返回类型。如果您返回不同的类型,它很可能会推断出
任何
。如有疑问,请明确指定返回类型:如果您错误地返回了错误的类型,这将导致编译错误。@bluenote10:在这种情况下不是。无论我在
案例中做什么
,编译器都会推断param1和param2的正确类型。例如,如果我这样做:
case\u=>println(“有一个错误!”)
返回
Unit
,但不影响param1和param2@Eduardo:我刚签入Scala 2.10:如果我将catch块中的类型更改为其他类型,编译器将
任何
推断为元组中的类型。为什么您认为这不会按预期工作?您可能希望捕获的内容不那么杂乱无章,但除此之外,它看起来是可行的,即使不是惯用的scala。@不明确:我已尝试将其更改为
case=>(“def1”、“def2”、“junk”)
,编译器没有抱怨,我将其解释为结果可能被忽略的迹象。而且,大多数情况下,一个人写的东西返回
单元
(比如打印错误消息等)。编译器如何知道何时要使用结果?编译器推断返回类型。如果您返回不同的类型,它很可能会推断出
任何
。如有疑问,请明确指定返回类型:如果您错误地返回了错误的类型,这将导致编译错误。@bluenote10:在这种情况下不是。无论我在
案例中做什么
,编译器都会推断param1和param2的正确类型。例如,如果我这样做:
case\u=>println(“有一个错误!”)
返回
Unit
,但不影响param1和param2@Eduardo:我刚签入Scala 2.10:如果我将catch块中的类型更改为其他类型,编译器将
任何
推断为元组中的类型。您是否确实尝试过这种方法?我认为您在
catch
中返回的内容被忽略了(例如,返回
Unit
是很常见的)爱德华多:不,不是。我刚刚在Scala 2.10中进行了检查。如果您使用:
val(param1,param2):Tuple2[String,String]=…
您将无法返回(“def1”、“def2”、“junk”)或(“def1”,42)。@bluenote10:很遗憾,我无法升级到2.10。这就是我提到我使用2的原因。9@Eduardo你说得对。我刚刚在2.9中进行了交叉检查:这只给出了一个编译器警告
警告:类型模式(String,String)中的非变量类型参数String未被选中,因为它被擦除消除了
@Eduardo-请查看更新,了解如何在2.9中安全地键入。您确实尝试过这个吗?我认为您在
catch
中返回的内容被忽略了(例如,返回
Unit
是很常见的)爱德华多:不,不是。我刚刚在Scala 2.10中进行了检查。如果您使用:
val(param1,param2):Tuple2[String,String]=…
您将无法返回(“def1”、“def2”、“junk”)或(“def1”,42)。@bluenote10:I无法返回