Как разделенный запятыми оператор возврата в Lua может действовать как вызов функции? - PullRequest
4 голосов
/ 30 октября 2019

Я новичок в Lua и пытаюсь выяснить, как выражение return в приведенной ниже функции squares используется в следующем фрагменте кода:

function squares(iteratorMaxCount)
   return square,iteratorMaxCount,0
end

Параметр square в операторе возврата относится к функции со следующей сигнатурой:

function square(iteratorMaxCount,currentNumber)

Меня смущает то, что return оператор выглядит как будто он возвращает три значения. То, что я думаю на самом деле делает, однако передает iteratorMaxCount и 0 в качестве аргументов для вызова функции square .

Может кто-нибудь объяснить мне, что происходит с этим синтаксисом? Как это служит вызовом функции, а не возвращает три значения? На мой взгляд, кажется, что оператор return должен быть записан квадрат возврата (iteratorMaxCount, 0) в отличие от квадрат возврата, iteratorMaxCount, 0 . Я знаю, что это явно неправильно, но я не могу понять, почему.

Я пробовал искать в Lua Manual, Lua Reference Guide и искать в Google, но я не могу найти ничего, что объясняет этот конкретный синтаксис. Кто-нибудь может указать мне правильное направление, пожалуйста?

Заранее спасибо.

Полный код ниже через Tutorialspoint

function square(iteratorMaxCount,currentNumber)

   if currentNumber<iteratorMaxCount
   then
      currentNumber = currentNumber+1
      return currentNumber, currentNumber*currentNumber
   end

end

function squares(iteratorMaxCount)
   return square,iteratorMaxCount,0
end  

for i,n in squares(3)
do 
   print(i,n)
end

1 Ответ

4 голосов
/ 30 октября 2019

squares действительно возвращает три значения, первое из которых является функцией. squares вообще не вызывает square.

Хитрость в том, как работает синтаксис for ... in. В справочном руководстве Lua 5.3, раздел 3.3.5 гласит:

A для , например:

for var_1, ···, var_n in explist do block end

эквивалентно коду:

 do
   local f, s, var = explist
   while true do
     local var_1, ···, var_n = f(s, var)
     if var_1 == nil then break end
     var = var_1
     block
   end
 end

Таким образом, после ключевого слова "in" должны следовать три значения:

  1. "функция итератора" для получения переменных в каждой итерации
  2. значение «состояния» для передачи в функцию каждый раз
  3. начальное значение для передачи в функцию в первый раз

После первого вызова функции,первое значение из предыдущего вызова передается обратно в следующий вызов функции. Когда первое значение, возвращаемое функцией - nil, цикл for заканчивается.

Так что в этом примере squares(max) предназначен для использования после "in" с использованием squareв качестве функции итератора, max в качестве «состояния», 0 в качестве начального значения и число и его квадрат в качестве значений данных цикла.

...