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