Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
[Обучение] Основы Lua.docx
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
66.67 Кб
Скачать

Функции

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

f = function( ... ) ... end

В скобках размещается список (возможно пустой) аргументов функции. Список аргументов функции может заканчиваться троеточием  —  в этом случае функция имеет переменное число аргументов. Между закрывающейся скобкой и оператором end размещается тело функции.

Для определения функции имеются следующие краткие формы:

function fname( ... ) ... end fname = function( ... ) ... end

local function fname( ... ) ... end local fname = function( ... ) ... end

function x.fname( ... ) ... end x.fname = function( ... ) ... end

function x:fname( ... ) ... end x.fname = function( self, ... ) ... end

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

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

Для вызова функций имеются следующие краткие формы:

f{...} f({...})

f('...') f'...'

f("") f""

f([[...]]) f[[...]]

x:f(...) x.f(x, ...)

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

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

Если функция имеет переменное число аргументов, то значения, не поставленные в соответствие ни одному из аргументов, могут быть получены при использовании специфического имени .... Это имя ведет себя как набор значений, возвращаемых функцией т.е. при его появлении внутри выражения или из середины списка значений используется только первое возвращаемое значение. Если же имя ... оказывается в последней позиции списка значений (в конструкторах таблиц, при множественном присваивании, в списке аргументов при вызове функции и в операторе return), то все возвращаемые значения помещаются в конец этого списка (правило дополнения списков). Для подавления такого поведения имя ... может быть помещено в круглые скобки. Превратить набор значений в список можно с помощью идиомы {...}.

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

function rename( arg )

arg.new = arg.new or arg.old .. ".bak"

return os.rename(arg.old, arg.new)

end

rename{ old = "asd.qwe" }

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

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

Имеется предопределенная функция unpack(), которая принимает массив, элементы которого проиндексированы с 1, а возвращает все его элементы. Эта функция может быть использована для вызова функций, принимающих переменное число аргументов с динамическим формированием списка фактических аргументов. Обратная операция производится следующим образом:

list1 = {f()} -- создать список из всех значений, возвращенных функцией f()

list2 = {...} -- создать список из всех значений, переданных в функцию

с переменным числом аргументов

Переменное число возвращаемых значений, правило дополнения списков и возможность передавать в функцию не все формальные параметры могут взаимодействовать нетривиальным образом. Часто функция (например foo()) возвращает ответ при нормальном завершении и nil и сообщение об ошибке при ненормальном. Функция assert(val, msg) генерирует ошибку с сообщением message (вызывая функцию error(msg)) если val имеет значение false или nil и возвращает значение val в противном случае. Тогда оператор

v = assert(foo(), "message")

в случае успеха присваивает переменной v значение, возвращаемое функцией foo(). В этом случае foo() возвращает одно значение, а assert() получает параметр msg, равный nil. В случае ошибки функция assert() получает nil и сообщение об ошибке.