在每次在循环块中创建新作用域的语言中,每次在该新作用域中都会创建本地循环变量的新本地副本?

发布于 2024-08-30 07:48:32 字数 1106 浏览 5 评论 0原文

似乎在 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,即使之前定义了 ii 也会被视为为循环定义的局部变量?

创建新作用域、每次通过循环创建新的 i 本地副本的操作似乎很繁重,因为如果我们稍后不调用这些函数,似乎也没有什么问题。那么当以后不需要调用这些函数时,C/Java 的解释器和编译器是否可以尝试优化它,以便每次都没有 i 的本地副本?

It seems that in language like C, Java, and Ruby (as opposed to Javascript), a new scope is created for each iteration of a loop block, and the local variable defined for the loop is actually made into a local variable every single time and recorded in this new scope?

For example, in 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

the print out is:

[MacBook01:~] $ ruby scope.rb
"1.8.6"
1
2
3
4
5
[MacBook01:~] $ 

So, it looks like when a new scope is created, a new local copy of i is also created and recorded in this new scope, so that when the function is executed at a later time, the "i" is found in those scope chains as 1, 2, 3, 4, 5 respectively. Is this true? (It sounds like a heavy operation).

Contrast that with

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

This time, the i is defined before entering the loop, so Ruby 1.8.6 will not put this i in the new scope created for the loop block, and therefore when the i is looked up in the scope chain, it always refer to the i that was in the outside scope, and give 5 every time:

[MacBook01:~] $ ruby scope2.rb
"1.8.6"
5
5
5
5
5
[MacBook01:~] $ 

I heard that in Ruby 1.9, i will be treated as a local defined for the loop even when there is an i defined earlier?

The operation of creating a new scope, creating a new local copy of i each time through the loop seems heavy, as it seems it wouldn't have matter if we are not invoking the functions at a later time. So when the functions don't need to be invoked at a later time, could the interpreter and the compiler to C / Java try to optimize it so that there is no local copy of i each time?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

瞄了个咪的 2024-09-06 07:48:32

这与此处讨论的主题类似: http:// math.andrej.com/2009/04/09/pythons-lambda-is-broken/ 。在某些编程语言中,当您循环变量时,循环结构的主体会绑定到一个递增的变量。在其他情况下,每次循环迭代都会实例化一个新的循环变量。

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

This is similar to the topic discussed here: http://math.andrej.com/2009/04/09/pythons-lambda-is-broken/ . In some programming languages, when you loop over a variable, the body of the loop construct is bound to one variable that increments. In others, a new loop variable is instantiated per iteration of the loop.

As for lexical scope, note that in JavaScript, functions are the only constructs that form scopes (braces for if, while, for, etc. do not). In C/C++, any pair of braces forms a scope.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文