Подтвердить что ты не робот

Зачем использовать блок do-end в Lua?

Я продолжаю пытаться найти ответы для этого, но не могу этого сделать. Я хотел знать, для чего используется блок do-end? Он просто говорит, что значения используются, когда это необходимо в моей книге, так как я могу использовать это?

Использую ли я его, чтобы уменьшить область локальных переменных, поместив функцию в цикл do-end и поместив локальные переменные за пределы функции, но внутри этого блока do-end, и переменные будут видны функцией? Но может ли функция еще быть вызвана?

Извините за то, что вы очень расплывчаты. Я надеюсь, что в этом есть смысл. Может быть, иллюстрированный пример может быть полезен ^^

4b9b3361

Ответ 1

Блоки do-end связаны с проблемой изменения переменных. По сути, когда вы используете идентификатор, какое значение оно имеет? Например, какие числа будут напечатаны при написании следующей программы?

local x = 10
if x > 0 then
    local x = 17
    print(x)
end
print(x)

Когда дело доходит до локальных переменных, Lua использует стандартную лексическую область, как это хорошо объясняется в разделе 4.2 в Программе в книге Lua. Лексическая область очень полезна по нескольким причинам:

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

  • Ограничение переменных ограничено, что помогает читать и позволяет избежать некоторых ошибок:

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

    • Если вы определяете переменную внутри внутренней области, вы не можете случайно использовать ее во внешних областях.

  • Лексическое определение позволяет некоторым очень выразительным идиомам, когда вы объединяете его с вложенными функциями (замыканиями).

Обычно вам не нужно беспокоиться о том, чтобы сами определять области переменных. Функции, циклы и условные обозначения автоматически вводят новые области видимости, и этого обычно достаточно, чтобы дать вашим переменным хорошо ограниченную область. Тем не менее, время от времени вы можете ввести некоторые дополнительные области из воздуха, и для этого мы можем использовать do-end. Программирование Lua имеет следующий пример, где вы хотите вычислить решения квадратичного уравнения, и вычисление имеет некоторые временные:

do
  local a2 = 2*a
  local d = sqrt(b^2 - 4*a*c)
  x1 = (-b + d)/a2
  x2 = (-b - d)/a2
end          -- scope of `a2' and `d' ends here
print(x1, x2)

Без блока do-end a2 и d могут быть случайно использованы после того, как они больше не нужны:

local a2 = 2*a
local d = sqrt(b^2 - 4*a*c)
x1 = (-b + d)/a2
x2 = (-b - d)/a2
print(x1, x2)

print(a2) -- OOPS! I wanted to say "print(a)"

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

Ответ 2

Да, блок do end может использоваться для ограничения объема переменных; чтобы функция, использующая эти переменные, видима, у вас есть несколько опций

  • Локализовать переменную, которая хранит функцию вне блока:

    local func    
    do
      local a = 0
      func = function(inc)
        a = a + inc
        return a
      end
    end
    
  • Используйте глобальную функцию:

    do
      local a = 0
      function func(inc)
        a = a + inc
        return a
      end
    end
    
  • Используйте метод:

    local tbl = {}
    do
      local a = 0
      function tbl:func(inc)
        a = a + inc
        return a
      end
    end
    

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

Ответ 3

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

do

  local i = 0

  function inc()
    i = i + 1
    return i
  end

  function dec()
    i = i - 1
    return i
  end

end