В теории языков программирования нелокальная переменная — это переменная, которая не определена в локальной области видимости . Хотя этот термин может относиться к глобальным переменным , он в основном используется в контексте вложенных и анонимных функций , где некоторые переменные не могут находиться ни в локальной , ни в глобальной области видимости .
В Lua они называются повышающими значениями функции. [1]
В следующем примере Python 3 есть вложенная функция inner
, определенная в области видимости другой функции outer
. Переменная x
является локальной для outer
, но нелокальной для inner
(и не глобальной):
def внешний (): x = 1 def внутренний (): нелокальный x x += 1 print ( x ) return внутренний
В Javascript локальность переменной определяется ближайшим var
оператором для этой переменной. В следующем примере x
является локальным, outer
так как содержит var x
оператор, а inner
не содержит. Следовательно, x нелокален для inner
:
функция внешняя () { вар х знак равно 1 ; функция внутренняя () { х += 1 ; консоль . журнал ( х ); } Вернуть внутренний ; }
В следующем примере Haskell переменная c
не является локальной в анонимной функции \x -> x + c
:
внешний = пусть c = 1 в карте ( \ x -> x + c ) [ 1 , 2 , 3 , 4 , 5 ]
Нелокальные переменные являются основной причиной того, что в языке программирования трудно поддерживать вложенные, анонимные функции высшего порядка и, следовательно, первоклассные функции .
Если вложенная функция или функции (взаимно) рекурсивны , компилятору становится сложно точно определить, где в стеке вызовов была выделена нелокальная переменная, поскольку указатель кадра указывает только на локальную переменную самой вложенной функции и между ними в стеке может находиться произвольное количество записей активации . Обычно это решается с помощью ссылок доступа или регистров отображения .
Если вложенная функция передается в качестве аргумента функции более высокого порядка, необходимо построить замыкание , чтобы найти нелокальные переменные. Если вложенная функция возвращается в результате своей внешней функции (или сохраняется в переменной), нелокальные переменные больше не будут доступны в стеке. Вместо этого они должны быть выделены в куче, а их время жизни выходит за рамки времени жизни внешней функции, которая их объявила и выделила. Обычно для этого требуется сбор мусора.