Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 变量的嵌套/内部范围_Scala_Scope - Fatal编程技术网

Scala 变量的嵌套/内部范围

Scala 变量的嵌套/内部范围,scala,scope,Scala,Scope,Scala中变量的作用域具体是什么 当我打开花括号时,我仍然可以访问外部变量的值(如果变量为,则修改它们): 但是奥德斯基在他的书第180页上说 在Scala程序中,内部变量被称为与外部变量类似的阴影, 因为外部变量在内部范围内不可见 这似乎更奇怪: scala> val a = 4 a: Int = 4 scala> { | println(a) | } 4 那么我要在内部范围中创建它的副本吗 scala> val a = 4 a: Int = 4

Scala中变量的作用域具体是什么

当我打开花括号时,我仍然可以访问外部变量的值(如果变量为,则修改它们):

但是奥德斯基在他的书第180页上说

在Scala程序中,内部变量被称为与外部变量类似的阴影, 因为外部变量在内部范围内不可见

这似乎更奇怪:

scala> val a = 4
a: Int = 4

scala> {
     | println(a)
     | }
4
那么我要在内部范围中创建它的副本吗

scala> val a = 4
a: Int = 4

scala> {
     | val a = 8
     | }
如果val是不可变的,为什么还要再说一遍

scala> val a = 4
a: Int = 4

scala> {
     | println(a)
     | val a = 8
     | println(a)
     | }
但对于这个,我得到了一个错误:

error: forward reference extends over definition of value a
              println(a)

块本身不会更改外部变量的可见性。仅当在内部范围内声明具有相同名称的变量时,如Odersky引号所述

您的前两个示例没有做到这一点,因此外部变量在内部范围内清晰可见,而Odersky的引用不适用。内部范围中的
a
与外部范围中的
a
相同,不涉及复制

然而,在第三个示例中,两个
a
s是两个独立的
val
变量,即内部
a
并没有重新定义外部
a
,只是根据奥德斯基的引文将其隐藏,例如:

val a = 4
println(a)  // prints 4 - outer a
{
  val a = 8;
  println(a)  // prints 8 - inner a
}
println(a)  // prints 4 - outer a in scope again
即,退出内部块后,您会看到外部
a
及其原始值仍然存在


但是,第三个示例中显示的代码非常模糊,因为如果不深入了解语言规范,就很难确定第一个
println(a)
语句所引用的变量。我手头没有确切的参考资料,但我相信编译器不允许这样的代码,因为这种风格本身就容易出错,但却没有任何好处。

块本身不会改变外部变量的可见性。仅当在内部范围内声明具有相同名称的变量时,如Odersky引号所述

您的前两个示例没有做到这一点,因此外部变量在内部范围内清晰可见,而Odersky的引用不适用。内部范围中的
a
与外部范围中的
a
相同,不涉及复制

然而,在第三个示例中,两个
a
s是两个独立的
val
变量,即内部
a
并没有重新定义外部
a
,只是根据奥德斯基的引文将其隐藏,例如:

val a = 4
println(a)  // prints 4 - outer a
{
  val a = 8;
  println(a)  // prints 8 - inner a
}
println(a)  // prints 4 - outer a in scope again
即,退出内部块后,您会看到外部
a
及其原始值仍然存在


但是,第三个示例中显示的代码非常模糊,因为如果不深入了解语言规范,就很难确定第一个
println(a)
语句所引用的变量。我手头没有确切的参考资料,但我相信编译器不允许这样的代码,因为这种风格本身就容易出错,但却没有任何好处。

如果在块中创建一个新代码,则新代码会与旧(外部)代码产生阴影。如果你没有,你指的是外面的那个

在块中的何处创建新块并不重要;如果它出现在任何地方,它会遮挡外部的一个

所以


编辑:让我们打开最后一个

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

如果在块中创建一个新的块,则新的块将遮挡旧的(外部)块。如果你没有,你指的是外面的那个

在块中的何处创建新块并不重要;如果它出现在任何地方,它会遮挡外部的一个

所以


编辑:让我们打开最后一个

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

我仍然很困惑,我只是无法理解这一点(我想这是我的错):现在我知道外壳是不同的,但我可以理解它是如何工作的,比如:martin@mintbox~$
a=5martin@mintbox~$(echo$a;a=8;echo$a)5 8martin@mintbox~$echo$a 5
在那里我可以看到创建的范围(对于var的副本,子shell不能影响外部变量的val,但是内部副本可以影响外部变量的val,但是您如何解释我的第一个示例,其中内部增量改变外部值?@mbrambley-内部增量是外部值的增量。您不会因为打开一些大括号而丢弃所有变量。这就像子shell一样在这方面进行分类:子对象仍然可以访问父对象中的所有内容,但可以添加自己的内容(或替换父对象的内容)。它实际上不是子类化,但这可能有助于您了解发生了什么。@mbrambley-是的,它会在执行任何操作之前扫描变量。(这是您可以在块的更下方引用
def
的方式。)我不确定到底有多少个过程。我在编译时注意到至少三个明显的过程。谢谢,我想我现在明白了-我想我会在内部作用域中避免使用同名的变量,直到我能想到它们的用法…现在我害怕自己的阴影,但是变量呢?如果我分配它们,变化会在外部可见吗?我的sim卡ilar(我猜)代码不起作用:var finalWorld:WorldModel=null LifeActors.run(world,new WorldModelListener{override def worldUpdated(world:WorldModel)={finalWorld=world},3)//3次迭代val-alive=finalWorld.getElements.filter(u.isAlive).该死,我不知道如何在这里粘贴代码,对不起,我仍然很困惑,我只是无法理解这一点(我想这是我的错):现在我知道外壳不同了,但我可以理解它是如何工作的,比如:martin@mintbox~$
a=5martin@mintbox~$(echo$a;a=8;echo$a) 5 8 martin@mintbox~$echo$a 5
在那里我可以看到创建的范围(对于var的副本,子shell不能影响外部变量的val,但是内部副本可以影响外部变量的val,但是您如何解释我的第一个示例,其中内部增量改变外部值?@mbrambley-内部增量是外部值的增量。您不会因为打开一些大括号而丢弃所有变量。这就像子shell一样在这方面分类: