为什么scala try块允许重新定义封闭范围中的变量?

时间:2013-02-20 12:24:45

标签: scala scope

使用Scala 2.10,以下编译没有错误。

val test = 1
try {
  val test = 2
}

查看生成的字节代码,我看到了:

int test = 1;
int test = 2;

这不奇怪吗?或者我错过了一些明显的东西?

3 个答案:

答案 0 :(得分:3)

局部变量的名称总是与范围更广的变量相同。通过在括号内声明它,您可以有效地保护自己不会意外地使用/覆盖其他地方使用的变量。不奇怪 - 但很有用!

答案 1 :(得分:2)

也许你试试这个可以清楚地了解最新情况

val test = 1
println(test)
try{
  val test = 2
  println(test)
}
println(test)

范围很重要。我希望你得到1 2 1 第二个test仅存在于try范围

答案 2 :(得分:2)

这与try无关。变量可以在任何块中相互遮挡,你可以将块放在任何地方:

val x = 0
if ({val x = 1; x*3}==0) {
  val x = 2; x + x + x
}
else x

这使得代码更具可移植性:您可以自由移动块,而不必担心外部的某些内容可能会发生冲突。 (嗯,不完全正确:哪些暗示在范围内仍然可能导致问题,但这比重复变量更不可能绊倒你。)

这是与Java不同的选择; Java的态度是你更可能忘记你的变量名并需要被提醒,而Scala是你可能意味着你所说的即使外部环境发生变化。这种情况是有道理的,因为Java专注于可变操作(隐藏一个可变变量实际上可能导致问题!)和Scala的默认不可变(因为你可以重用像i和x这样的短变量,所以甚至可能需要遮蔽外部不可变变量)为了你的内心)。