2013-02-28 78 views
1

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

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

+1

为什么你认为这不会按预期工作?你可能希望在捕捉什么时候少一点混杂,但除此之外,它看起来可行,即使不是惯用的scala。 – Impredicative 2013-02-28 12:18:03

+0

@Impredicative:我已经尝试将它改为'case _ =>(“def1”,“def2”,“junk”),编译器并没有抱怨,我把它解释为一个表示结果可能被忽略的标志。此外,大多数情况下,一个写入返回“Unit”的东西(如打印错误消息等)。编译器如何知道何时使用结果? – Eduardo 2013-02-28 12:19:49

+0

编译器推断返回类型。如果你返回不同的类型,它很可能会推断“任何”。如有疑问,请明确指定返回类型:如果您错误地返回错误类型,将导致编译错误。 – bluenote10 2013-02-28 12:26:57

回答

3

这是可行的,但它开辟了一个运行时错误的,因为

val (a,b) = whatever 

的可能性,只要whateverTuple2 --in特别是超可称为,它可能是AnyRefAny,这实际上是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 = perch和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) 

到得到捕获的类型检查。

+0

你真的尝试过吗?我认为你在'catch'中返回的内容会被忽略(例如,返回“Unit”比较常见) – Eduardo 2013-02-28 12:35:36

+0

Eduardo:不,它不是。我刚刚在Scala 2.10中进行了检查。如果你使用:'val(param1,param2):Tuple2 [String,String] = ...'你将无法返回(“def1”,“def2”,“junk”)和(“def1” 42)。 – bluenote10 2013-02-28 12:37:38

+0

@ bluenote10:不幸的是我无法升级到2.10。这就是为什么我提到我在使用2。9 – Eduardo 2013-02-28 12:38:30