В языках, которые создают новую область каждый раз в блоке цикла, новая локальная копия локальной переменной цикла создается каждый раз в этой новой области? - PullRequest
2 голосов
/ 29 апреля 2010

Кажется, что в таких языках, как 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 каждый раз?

1 Ответ

1 голос
/ 29 апреля 2010

Это похоже на тему, обсуждаемую здесь: http://math.andrej.com/2009/04/09/pythons-lambda-is-broken/. В некоторых языках программирования, когда вы зацикливаете переменную, тело конструкции цикла связывается с одной переменной, которая увеличивается. В других случаях создается новая переменная цикла на каждую итерацию цикла.

Что касается лексической области действия, обратите внимание, что в JavaScript функции являются единственными конструкциями, которые формируют области видимости (скобки для if, while, for и т. Д. - нет). В C / C ++ любая пара скобок образует область видимости.

...