Lua: как правильно создавать вложенные функции

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

function stats(input)
    height, weight, name, age, gender, relate = string.match(input, "(%d*)ft,(%d*)lbs,(%w*),(%d*),(%u*),(%u)")
    if name then
        function nameInit(relate)
            relateTable = {["F"] = "Friend", ["R"] = "Relative"}
            for k,v in pairs (relateTable) do
                if relate == k then
                    relship = v
                    return relship
                end
            end
        end
    end
    person = name.." is "..age.." years old, weighs "..weight.." and blah blah blah....
    return person
end
print (stats("5.8ft, 160lbs, Mike Scott, 19, M, F"))

Очевидно, что эта тема не практична, но я пытаюсь сделать то же самое с точки зрения конечного ответа. Сейчас я получаю lua: filename: attempt to concatenate global 'relship' (a nil value)? Я могу получить ответ, который хочу, без вложенной функции. Но когда я пытаюсь уточнить ответ, который я хотел бы получить, и помещаю эту функцию в глобальную функцию, я начинаю получать эти ответы. Кажется, это моя проблема каждый раз, когда я пытаюсь использовать функции внутри других функций. Я могу создать две отдельные глобальные функции и распечатать результаты любой из них. Но в ту минуту, когда я пытаюсь использовать одно в другом, я облажался. Любой, кто может потратить некоторое время, чтобы помочь новичку лучше понять, что он делает неправильно, был бы великолепен! Спасибо всем.


person Pwrcdr87    schedule 14.05.2014    source источник
comment
Куда ты звонишь nameInit? Вы только определяете это здесь, но ничего не вызываете.   -  person Colonel Thirty Two    schedule 15.05.2014
comment
Кроме того, почему бы не изменить stats(input) на stats(ht, wt, name, age, gender, relate) вместо использования string.match, чтобы сопоставить их все?   -  person Josh    schedule 15.05.2014
comment
Соглашаясь с @ColonelThirtyTwo, вы также не объединяете relship нигде в этом фрагменте кода, поэтому он не может генерировать эту ошибку. Вам необходимо предоставить нам более точный и полный список кодов, если вы хотите получить помощь. (В качестве общего совета вы также хотите использовать локальные переменные, включая функции, вместо того, чтобы везде использовать глобальные.)   -  person Etan Reisner    schedule 15.05.2014
comment
@ColonelThirtyTwo Спасибо за помощь!   -  person Pwrcdr87    schedule 15.05.2014
comment
@EtanReisner Извините, что не указал местных жителей. В моем коде я использую его. Когда я набирал свой пример кода, я совершенно забыл об этом. Мои извенения. Но я ценю вашу помощь!   -  person Pwrcdr87    schedule 15.05.2014
comment
@ Джош, я не знаю другого способа получить ввод из внешнего источника и сопоставить нужные мне переменные с полученным вводом?   -  person Pwrcdr87    schedule 15.05.2014
comment
Все случаи использования ключевого слова function являются вложенными, поскольку каждый фрагмент исходного кода компилируется как тело функции. Следовательно, если фрагмент определяет функцию, эта функция является вложенной.   -  person Tom Blodget    schedule 16.05.2014


Ответы (1)


Основываясь на вашем утверждении, что «функции внутри него потребуются для перевода этого ввода и возврата результатов для последующего использования», я не уверен, что вложенные функции - это то, что вам нужно. Вы говорите, что когда у вас есть две глобальные функции, ваш код работает:

function func1(args)
    ...
end

function func2(args)
    ...
end

но когда вы вкладываете (например) func1 внутрь func2, это больше не работает. Lua позволяет вам определять вложенные функции, но я могу придумать только две причины для их использования:

  1. чтобы вернуть функцию, которая инкапсулирует задачу, обычно с некоторыми аргументами и/или локальными переменными функции-оболочки в качестве значений upvalue.
  2. для инкапсуляции некоторой логики в функцию, которая будет вызываться из функции-оболочки, без необходимости вызова каких-либо других функций.

Например, случай 1:

function func2(a, b, c)
   function func1()
       do something with a, b, c eventhough they are not args of func1
       return result
   end
   return func1
end

someFunc = func2(1,2,3)
....
result = someFunc() -- calls func1 created inside func2, using 1,2,3 

Например, случай 2:

function func2(a, b, c)
   function func1()
       do something with a, b, c eventhough they are not args of func1
       return result
   end
   result = func1()
   ...
end

func2(1,2,3)

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

person Oliver    schedule 15.05.2014