2014-01-26 2 views
4

Я занимаюсь большей частью своего программирования на Python, и я использую методы ООП для большинства моих проектов. Недавно я начал изучать библиотеку игр и движок Love2D. Мне удалось настроить некоторые настройки, а затем подумал о создании класса GameObject. Но что это? У Lua нет классов! В нем есть столы, метатеги и другие подобные вещи. У меня много проблем с головами или хвостами, даже после того, как я прочитал документацию несколько раз.Ощущение ООП в Lua

Рассмотрим следующий пример:

catClass = {} 
catClass.__index = catClass 
catClass.type = "Cat" 

function catClass.create(name) 
    local obj = setmetatable({}, catClass) 
    obj.name = name 
    return obj 
end 

cat1 = catClass.create("Fluffy") 
print(cat1.type) 

cat2 = catClass.create("Meowth") 

cat1.type = "Dog" 

print(cat1.type) 
print(cat2.type) 
print(catClass.type) 

Выход этого заключается в следующем:

Cat 
Dog 
Cat 
Cat 

То, что я не понимаю, почему меняется cat1.type к «Собака» не вызывает тождественны изменения в cat2 и catClass. Создает ли метаданные копию таблицы? Google не предоставил полезных результатов (очень мало хороших объяснений Lua).

ответ

6

Когда вы индексируете таблицу, а ключ не существует, Lua будет смотреть, существует ли метатет для таблицы. Если это произойдет, то он будет использовать ключ __index этого метаметода для повторной индексации вашего ключа.

Когда вы создали cat1, он унаследовал catClass metatable.Затем, когда вы проиндексировали type, он увидит, что cat1 не имеет записи в таблице, которая называется type, и, таким образом, она просматривает метаданные, чтобы ее найти.

Затем вы устанавливаете type на cat1 в Dog, который только устанавливает ключ таблицы самого cat1, не метатаблицу. Поэтому, когда вы указали cat1 снова за type, вы получаете Dog, а не Cat.

Если вы идете на http://www.lua.org/, есть документация и несколько старых копий программирования в Lua, написанных авторами самой Lua.

4

См. Документацию setmetatable. Возвращенная таблица - это таблица, указанная в первом аргументе.

Это другая таблица для каждого вызова create (спасибо {}), и каждая новая таблица также отличается от используемой метатегии. Копия не была сделана, но была создана таблица , которая затем «привязана» к метрической.

Таким образом, существует три различных таблицы в выше - cat1 (с мтом catClass), cat2 (также с мтом catClass) и самой catClass. Изменение cat1, как это сделано, не влияет на две другие таблицы.


См Lua Metatables Tutorial; использование __index, представленное в metatable, эффективно эмулирует разрешение [прототип] JavaScript.

Когда вы смотрите таблицу с ключом, независимо от того, что ключ, и значение не было назначено для этого ключа .. Lua будет искать __index ключ в таблицы metatable .. Если __index содержит таблицу, Lua будет искать ключ, первоначально используемый в таблице, принадлежащей __index. не

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

Смежные вопросы