有关Scala中变量的范围的确切处理是什么?
当我打开大括号时,我仍然可以访问外部变量的值(并在变量时修改它们):
scala> var mmm = 4
mmm: Int = 4
scala> {
| println(mmm)
| mmm += 2
| println(mmm)
| }
4
6
scala> println(mmm)
6
Run Code Online (Sandbox Code Playgroud)
但奥德斯基在第180页或他的书中说过
在Scala程序中,内部变量被称为遮蔽一个类似命名的外部变量,因为外部变量在内部范围内变得不可见.
这看起来更怪异:
scala> val a = 4
a: Int = 4
scala> {
| println(a)
| }
4
Run Code Online (Sandbox Code Playgroud)
那么我是否在内部范围内获得了它的副本?
scala> val a = 4
a: Int = 4
scala> {
| val a = 8
| }
Run Code Online (Sandbox Code Playgroud)
如果它不可变,我为什么还能再说val呢?
scala> val a = 4
a: Int = 4
scala> {
| println(a)
| val a = 8
| println(a)
| }
Run Code Online (Sandbox Code Playgroud)
但对于这个我得到一个错误:
error: forward reference extends over definition of value a
println(a)
Run Code Online (Sandbox Code Playgroud)
如果在块中创建一个新的,则新的阴影会影响旧的(外部).如果你不这样做,你可以参考外面的那个.
块中创建新块的位置无关紧要; 如果它出现在任何地方,它会遮挡外部的一个.
所以,
val a = 5
{ println(a) } // This is outer a
val a = 5
{ val a = 8; println(a) } // This is inner a
val a = 5
{ println(a); val a = 8 } // This is broken
// you try to print the inner a
// but it doesn't exist yet
Run Code Online (Sandbox Code Playgroud)
编辑:让我们解压缩最后一个
val a = 5
// Okay, I have something called a
{ // Oh, new block beginning! Maybe there are local variables
println(a)
val a = 8 // Yeah, there's one!
// And it's got the same name as the outer one
// Oh well, who needs the outer one anyway?
}
// Waitaminute, what was that block supposed to do?
{
println(a) // Inner block has an a, so this must be the inner a
val a = 8 // Which is 8
}
// Hang on, operations happen in order
{
println(a) // What inner a?!
// Abort, abort, abort!!!!
Run Code Online (Sandbox Code Playgroud)