Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.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
Loops 在每次在循环块中创建新作用域的语言中,每次在新作用域中创建局部循环变量的新局部副本?_Loops_Scope_Closures - Fatal编程技术网

Loops 在每次在循环块中创建新作用域的语言中,每次在新作用域中创建局部循环变量的新局部副本?

Loops 在每次在循环块中创建新作用域的语言中,每次在新作用域中创建局部循环变量的新局部副本?,loops,scope,closures,Loops,Scope,Closures,在像C、Java和Ruby这样的语言中(与Javascript相反),循环块的每次迭代都会创建一个新的作用域,而为循环定义的局部变量实际上每次都会变成一个局部变量,并记录在这个新的作用域中 例如,在Ruby中: p RUBY_VERSION $foo = [] (1..5).each do |i| $foo[i] = lambda { p i } end (1..5).each do |j| $foo[j].call() end 打印件为: [MacBook01:~] $ rub

在像C、Java和Ruby这样的语言中(与Javascript相反),循环块的每次迭代都会创建一个新的作用域,而为循环定义的局部变量实际上每次都会变成一个局部变量,并记录在这个新的作用域中

例如,在Ruby中:

p RUBY_VERSION

$foo = []

(1..5).each do |i|
  $foo[i] = lambda { p i }
end

(1..5).each do |j|
  $foo[j].call()
end
打印件为:

[MacBook01:~] $ ruby scope.rb
"1.8.6"
1
2
3
4
5
[MacBook01:~] $ 
因此,当创建一个新的作用域时,
i
的一个新的本地副本也会被创建并记录在这个新的作用域中,这样当函数在以后执行时,“i”在这些作用域链中分别被发现为1、2、3、4、5。这是真的吗?(这听起来像是一项繁重的行动)

与之相比

p RUBY_VERSION

$foo = []

i = 0

(1..5).each do |i|
  $foo[i] = lambda { p i }
end

(1..5).each do |j|
  $foo[j].call()
end
这一次,在进入循环之前定义了
i
,因此Ruby 1.8.6不会将此
i
放入为循环块创建的新范围中,因此当在范围链中查找
i
时,它总是引用范围外的
i
,每次都给出5:

[MacBook01:~] $ ruby scope2.rb
"1.8.6"
5
5
5
5
5
[MacBook01:~] $ 
我听说在Ruby 1.9中,
I
将被视为循环的本地定义,即使前面定义了
I


每次通过循环创建一个新的作用域、创建一个新的
i
本地副本的操作似乎很繁重,因为如果我们以后不调用这些函数,这似乎无关紧要。因此,当以后不需要调用函数时,C/Java的解释器和编译器是否可以尝试对其进行优化,以便每次都没有
i
的本地副本?

这与此处讨论的主题类似:。在某些编程语言中,当在变量上循环时,循环构造的主体绑定到一个递增的变量。在其他情况下,每次循环迭代都会实例化一个新的循环变量

至于词法作用域,请注意,在JavaScript中,函数是构成作用域的唯一构造(如果
,等等,则不构成作用域)。在C/C++中,任何一对大括号都构成一个作用域