Функция перезаписи только для конкретного экземпляра в LUA - PullRequest
0 голосов
/ 08 февраля 2019

Я в основном не ищу ответа о том, как что-то сделать, но я нашел, как это сделать, но хочу больше информации.Надеюсь, что этот вопрос в порядке здесь.Так как я только что обнаружил этот код игры, которую я моддирую, я понятия не имею, для чего мне гуглить.

В Lua я могу иметь, например:

Account = {balance = 0}
function Account.withdraw (v)
     self.balance = self.balance - v
end

Я могу иметь (в другом файле lua)

function Account.withdrawBetter (v)
    if self.balance > v then 
      self.balance = self.balance - v
    end
end

.... - где-то вкакая-то функция с экземпляром Account: a1.withdraw = a1.withdrawBetter `

Как называется этот« метод », поэтому я могу найти больше информации о нем (возможные подводные камни, соображения производительности и переопределение / перезапись), так далее)?примечание: я изменяю withdraw только для конкретного экземпляра (a1), а не для каждого экземпляра учетной записи.

Бонусный вопрос: есть ли другие oo языки программирования с такой возможностью?

Спасибо

1 Ответ

0 голосов
/ 08 февраля 2019

OO в Lua

Прежде всего, следует отметить, что Lua не реализует объектно-ориентированное программирование;в нем нет понятия объектов, классов, наследования и т. д.

Если вы хотите, чтобы ООП в Lua, вы должны реализовать это самостоятельно.Обычно это делается путем создания таблицы, которая действует как «класс», сохраняя «методы экземпляра», которые на самом деле являются просто функциями, которые принимают экземпляр в качестве первого аргумента.

Затем наследование достигается наличием«Конструктор» (также просто функция) создает новую таблицу и устанавливает для нее метатабельность с полем __index, указывающим на таблицу классов.При индексации «экземпляра» по ключу, которого у него нет, он вместо этого будет искать этот ключ в классе.

Другими словами, таблица «экземпляра» может вообще не иметь функций, ноиндексируя его, например, с помощью "withdraw", просто попробуйте вместо этого индексировать класс.

Теперь, если мы возьмем одну таблицу «instance» и добавим к ней поле withdraw, Lua увидит, что онаимеет это поле и не надо искать его в классе.Можно сказать, что это значение shadows значение в таблице классов.

Как называется эта "техника"

Это недействительно есть, но вы обязательно должны посмотреть метатаблицы.

На языках, которые делают , поддерживают такие вещи, как в Ruby (см. ниже), это часто делается с одноэлементными классами, что означаетчто они имеют только один экземпляр.

Замечания по производительности

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

Итак, вдругими словами, это на самом деле быстрее .Он занимает немного больше места, но не так много ( технически это может быть довольно много, но вам не стоит об этом беспокоиться. Тем не менее, здесь вы можете прочитать очто , если хотите).

Какие-либо другие oo языки программирования с такой возможностью?

Да, их много.Ruby - хороший пример, где вы можете сделать что-то вроде

array1 = [1, 2, 3]
array2 = [4, 5, 6]

def array1.foo
  puts 'bar'
end

array1.foo # prints 'bar'
array2.foo # raises `NoMethodError`
...