Добавлен , опубликован

Lua для чайников

Содержание:
Функции — один из типов данных. В неё можно записать любое количество необходимых операций, а затем вызвать по желанию. В неё вообще можно всё что угодно записывать.

13.1. Простые функции.

Выглядят так:
Синтаксис:
--упрощенная или сокращенная форма записи функции
function ...:...()
  ...
end
function — зарезервированный оператор, с которого начинается каждая функция. То, что перед двоеточием, — это имя файла, в котором эта функция создаётся. Между двоеточием и скобками пишется имя функции. Оно может быть любым (только главное, чтобы в одном файле не было двух или более функций с одним и тем же именем файла и названием функции). В скобках записываются её аргументы.
Пример функции:
script.lua:
function script:newfunc()
  print("First function was created!");
end
заметка: script:newfunc(), где script - чаще всего таблица. В след разделах рассмотрим пример, как создавать таблицы. Такая запись удобна для работы с таблицей, и ее объектами. Вы можете различные функции-обертки создать для работы.
примеры применения
можно найти различные применения, как в душе удобно:
QuadTree = {} --так инициируют таблицу
QuadTree.new = function(x, y, w, h) --так инициируем функцию
	return {posx=x,posy=y,width=w, height=h}
end

table = QuadTree.new(1,2, 3, 4) --вызываю функцию объекта
print(tostring(table.posx)) --вернет 1
print(tostring(table.posy)) --вернет 2
print(tostring(table.width)) --вернет 3
print(tostring(table.height)) --вернет 4
или
--инициируем таблицу Vector3 = {..--сюда записывают данные ккорд x, y, z ( см. пример ниже)..}
Vector3 = {
    -- Create a new vector from coords. Skip the coords to create a zero vector
    new = function(self, x, y, z) --можно иниицировать функцию new = function(аргументы)
      local o = {}
      setmetatable(o,self)
      o.x = x or 0.
      o.y = y or 0.
      o.z = z or 0.
      return o
    end
}

v = Vector3:new(1,2,3)
print(v.x,v.y,v.z) --печатает 1	2 3
Данная функция не заработает, пока её не вызвать. Сделать это можно так:
script:newfunc(); -- First function was created!
Если вызов функции происходит из того же файла, в котором она было создана, можно воспользоваться оператором self:
self:newfunc(); -- First function was created!
При вызове из другого файла применяется способ выше. Но и для этого вызова никто не запрещает использование способа выше.
Вообще, название файла можно в принципе отсечь:
--func это имя
function func()
  print("Second function");
end
Тогда вызов всегда будет выглядеть так:
func();
Но всё же для того, чтобы облегчить другим поиск той или иной функции, лучше писать название файла.
Также к функциям других файлов можно обращаться из иных файлов, чтобы внести в неё свои изменения, не трогая при этом оригинальные файлы:
anotherscript.lua:
function script:newfunc()
  print("Function was edited first time!");
end
еще одна заметка: чтобы обращаться к функции объекта, нужно инициировать объект (таблицу), и функцию
object:new() --вы не можете вызвать, тк объект и функция не существует.
Теперь при последующих вызовах функции она будет выдавать другое содержимое, — то, которое написано чуть выше.

13.2. Аргументы.

Аргументы являются локальными переменными функции. Записываются в скобки. Их может быть несколько или всего один.
Пример:
script.lua
function script:stick(a,b,c);  
  a = 1;  
  b = 2;  
  c = 3;  
  print(a + b + c);  
end

self:stick(a,b,c); -- 5
Аргументы можно заменять на другие значения:
script.lua
function script:stick2(a,b,c);
  print(a + b + c);  
end

self:stick2(2,2,2); -- 6
Это может повлиять на содержимое функции.
Если не вызывать какие-либо аргументы, то им присваивается значение nil. А если вызвать больше аргументов, чем есть, тогда все лишние аргументы удалятся:
self:stick2(); -- все аргументы равны nil -- вылезет ошибка
self:stick2(1); -- аргументы b и c равны nil -- вылезет ошибка
self:stick2(1,2); -- аргумент c равен nil -- вылезет ошибка
self:stick2(1,2,3,4); -- 4 -- лишнее -- он просто удалится, и всё будет нормально

13.2.1. Переменное число аргументов.

Примечание автора: для того чтобы лучше понимать этот параграф, необходимо знать таблицы — §14. Лучше всего будет пропустить сейчас этот параграф и вернуться к нему после изучения таблиц.
Но выбор, конечно, остаётся за читающим.
Это значит, что функция может иметь сколько угодно много аргументов, и при вызовах их количество можно будет изменять. Для определения переменного числа аргументов в скобках надо записать оператор «...» (многоточие):
function func(...)
  ...
end
Все аргументы, скрытые за многоточием, собираются в локальную таблицу arg. У этой таблицы есть явное поле n, которое возвращает количество аргументов, скрытых за многоточием:
funcion func(...)  
  print(arg.n);
end

func(1,2,3); -- 3
func(1,4,562,6,26,); -- 5
Например, нужно написать в консоль все аргументы скрытые за многоточием. Сделать это можно так:
function func(...)  
  for i=1,arg.n do  
  print(arg[i]);
  end  
end

func(1,2,3,4,5); --[[
1
2
3
4
5
]]
Или так:
function func(...)  
  print(...);
end

func(1,2,3,4,5); -- 1 2 3 4 5
Но лучше всё же первый вариант.
Также возможно совмещать явные аргументы со скрытыми за многоточием:
function func(a,b,...)  
  print(a+b);

  for i=1,arg.n do  
  print(arg[i]);  
  end  
end

func(2,2,87,0,9); --[[4
87
0
9
]]
Напоследок скажу о том, что таблицу arg всё же лучше предопределить самостоятельно (так как в некоторых версиях Lua это приходится делать принудительно, иначе будет ошибка) таким образом:
local arg = {...};

13.3. Оператор return в функциях.

Этот оператор уже не раз встречался ранее. Настало время рассказать о его применении в функциях.
Во-первых, его можно применять как блокиратор выполнения функции. То есть, предположим, что функция не должна выполнится при том условии, если переменная не будет существовать. Можно, конечно, это сделать через условия:
a = nil;  

function func()  
  if a then  
  print(a);  
  end  
end
Но гораздо удобнее и быстрее воспользоваться оператором return:
a = nil;  

function func()  
  if not a then return end  

  print(a);  
end  

func(); -- не тут-то было. Функция не выполняется, потому что a -- nil  

a = "Hello!";  

func(); -- другое дело. Напечатается: «Hello!»
return можно использовать в любом месте функции. Главное, чтобы он был внутри условия или блока do ... end:
function func(param)  
  local state = nil;  

  if param then  
  state = true;  
  else  
  state = false;  
  end  

  if not state then return end  

  print(state);  
  print(param);  
end  

func(); --ничего не произойдёт. Печаль <img src="/.s/sm/1/sad.gif" border="0" align="absmiddle" alt="sad" />  
func(5); --[[true  
5  
]]
Во-вторых, оператор может служить для возвращения одного или нескольких аргументов или переменных:
function func(n,m)  
  return n + m;  
end
После чего эту функцию можно использовать как обычную переменную:
local sum = func(2,2);  
print(sum); -- 4
Можно возвращать сколько угодно переменных:
param1,param2,param3 = 1,2,3;  

function func()  
  return param1,param2,param3;  
end  

local a,b,c = func();  
print(a*b*c); -- 6
Если функция возвращает несколько параметров, но нужны не все, а ненужные надо куда-то пристроить, их можно проигнорировать оператором «_»:
local _,b,_ = func();  
print(b*2); -- 4

13.4. Операторы break и return в Lua

Оператор break прерывает цикл (while, repeat или for), в теле которого встречается. В результате выполнения оператора break управление передается первой инструкции, следующей непосредственно за оператором цикла.
for i = 1,#a do -- ищем в массиве отрицательное значение
   if a[i] < 0 then -- если найдено...
      index = i -- сохраняем индекс найденного значения...
      break -- и прерываем цикл
   end
end
Оператор return возвращает результаты из функции (или блока).
function f (x)
   return x^2
end
Оператор return может просто завершать работу функции (блока), не возвращая никаких результатов.

Обратите внимание

Операторы break и return могут быть только последними операторами блока (иначе следующие за ними операторы никогда не выполнятся). Если действительно необходимо вставить return или break в середину блока, например, чтобы временно отключить выполнение части кода функции, эти операторы следует заключить в свой блок do–end.
function f1 (x)
   return -- НЕВЕРНО!
   <другие операторы>
end
                                     
function f2 (x)
   do return end -- Правильно
   <другие операторы>
end

Остались вопросы? Задайте их сообществу! Задать вопрос
`
ОЖИДАНИЕ РЕКЛАМЫ...