4.2 - Локальные переменные и Блоки

Кроме глобальных переменных, Lua поддерживает переменные локальные. Локальные переменные создаются оператором local:

    j = 10         -- глобальная переменная
    local i = 1    -- локальная переменная
В отличие от глобальных, локальные имеют область видимости, ограниченную блоком, в котором она объявлена. Блоком являются тело управляющей конструкции, тело функции или chunk (файли или строка кода, где объявлена переменная).
    x = 10
    local i = 1        -- локальная для chank`а
    
	 while i<=x do
      local x = i*2    -- локальная для тела цикла while
      print(x)         --> 2, 4, 6, 8, ...
      i = i + 1
    end

    if i > 20 then
      local x          -- локальная для тела условия "then"
      x = 20
      print(x + 2)
    else
      print(x)         --> 10  (глобальная)
    end

    print(x)           --> 10  (глобальная)
Будте осторожны - данный пример, введенный в интерактивном режиме, будт работать не так, как ожидалось. Вторая строка, local i = 1, является полным chunk`ом. Как только вы введете эту строку, Lua выполнит ее и со следующей строки начнет новый chunk. К тому времениы, объявление local будет уже недействительно. Для выполнения таких примеров в интерактивном режиме, вы должны заключить весь код в блок do.

Хорошим стилем программирования является использование локальных переменных всегда, когда это возможно. Локальные переменные помогают избегать хаоса излишних имен в глобальном окружении. Кроме того, доступ к локальным переменным осуществляется быстрее, чем к глобальным.

Lua рассматривает объявление локальной переменной как оператор. По существу, можно помещать объявление локальной переменной везде, где можно поместить оператор. Область видимости начинается после объявления и продолжается до конца блока. Объявление может содержать инициализирующее присваивание, работающее как стандартный оператор присваивания: лишние значения отбрасываются; лишние переменные устанавливаются в nil. В особых случаях, если при объявлении не производится начальное присваивание, все переменные инициализируются значением nil.

    local a, b = 1, 10
    if a<b then
      print(a)   --> 1
      local a    -- подразумевается '= nil'
      print(a)   --> nil
    end          -- конец блока 'then'
    print(a,b)   -->  1   10

Часто встречается в Lua идиома

    local foo = foo
Этот код создает локальную переменную foo и инициализирует ее значением глобальной переменной foo. Эта идиома удобна, когда необходимо сохранить оригинальное значение foo на случай, если какая-либо другая функция изменит значение глобальной переменной foo; этотакже ускоряет доступ к переменной foo.

Т.к. многие языки заставляют объявлять все локальные переменные в начале блока (или процедуры), некоторые люди считают плохой практикой использовать объявления в середине блока. Совсем наоборот: при объявлении переменных только тогда, когда в них возникает необходимость, редко объявления происходят без инициализации (а следовательно, вы реже забываете инициализировать переменные). Кроме того, уменьшение области видимости увеличивает читабельность кода.

Можно блок выделять явно, ограничивая его ключевыми словами do-end. Блоки do могут быть удобны, когда есть необходимость тонкого управления областью видимости одной или более локальной переменной:

    do
      local a2 = 2*a
      local d = sqrt(b^2 - 4*a*c)
      x1 = (-b + d)/a2
      x2 = (-b - d)/a2
    end          -- видимость 'a2' и 'd' заканчивается здесь
    print(x1, x2)

Hosted by uCoz