Нелокальная переменная (Uylktgl,ugx hyjybyuugx)

Перейти к навигации Перейти к поиску

В теории языков программирования, нелокальная переменная — переменная, которая не определена в локальной области видимости. Хотя термин может относиться к глобальным переменным, он в первую очередь используется в контексте вложенных и анонимных функций, где некоторые переменные могут принадлежать как не локальной так и не глобальной области видимости.

В языке программирования Lua они называются upvalues.[1]

Вложенные функции

[править | править код]

В примере вложенной функции на языке программирования Python 3, который указан ниже, функция inner определена в области видимости другой функции — outer. Переменная x локальна по отношению к функции outer, но не локальна по отношению к функции inner (и не глобальна в то же время):

def outer():
    x = 1
    def inner():
        nonlocal x
        x += 1
        print(x)
    return inner

В языке программирования JavaScript, местонахождение переменной определяется с помощью ближайшего выражения var для этой переменной. В следующем примере, переменная x локальна по отношению к функции outer, так как она содержит выражение var x, в то же время функция inner нет. Таким образом x не локальна по отношению к функции inner:

function outer() {
    var x = 1;
    function inner() {
        x += 1;
        console.log(x);
    }
    return inner;
}

Анонимные функции

[править | править код]

В примере на языке Haskell, который следует далее в анонимной функции \x -> x + c переменная c нелокальная:

outer = let c = 1 in map (\x -> x + c) [1, 2, 3, 4, 5]

Проблемы с реализацией

[править | править код]

Нелокальные переменные являются основной причиной сложности поддержки вложенных, анонимных, высшего порядка и тем самым первого класса функций в языках программирования.

Если вложенная функция или функции (взаимно) рекурсивны, то становиться сложно для компилятора знать точно, где в стеке вызовов была выделена память для нелокальной переменной, так как указатель кадра указывает только на саму локальную переменную вложенной функции и может существовать произвольное количество записей активации в стеке. Обычно эта проблема решается с использованием access links или display registers.

Если вложенная функция передается как аргумент в функцию высшего порядка замыкание, должно быть построено для нахождения нелокальных переменных. Если вложенная функция возвращается как результат из своей внешней функции (или хранится в переменной) нелокальные переменные не будут более доступны в стеке. Вместо этого они должны быть выделены в куче и время их жизни будет дольше времени жизни внешней функции, которая объявила и выделила их. В общих случаях для этого требуется сборщик-мусора.

Примечания

[править | править код]