Я запутался в разнице между вызовами функций через .
и через:
> x = {foo = function(a,b) return a end, bar = function(a,b) return b end, }
> return x.foo(3,4)
3
> return x.bar(3,4)
4
> return x:foo(3,4)
table: 0x10a120
> return x:bar(3,4)
3
Что :
делает?
Ответы:
Двоеточие предназначено для реализации методов, которые передаются
self
в качестве первого параметра. Такx:bar(3,4)
должно быть так же, какx.bar(x,3,4)
.источник
self
будет ли объект указываться в качестве первого параметра, и от значения его свойств.object.method(object,args)
извлекаетсяobject
дважды, аobject:method(arg)
извлекаетсяobject
только один раз. Еслиobject
это глобальное, повышенное значение или поле таблицы, то:
оно быстрее, чем.
..
никогда не быстрее чем:
.Для определения это в точности то же самое, что и указание self вручную - при компиляции он даже выдаст тот же байт-код. Т.е.
function object:method(arg1, arg2)
такой же как иfunction object.method(object, arg1, arg2)
.При использовании
:
это почти то же самое, что.
и специальный вид вызова, который будет использоваться внутри, чтобы убедиться, чтоobject
любые возможные побочные эффекты вычислений / доступа рассчитываются только один раз. Вызовobject:method(arg1, arg2)
в остальном такой же какobject.method(object, arg1, arg2)
.источник
Чтобы быть полностью точным, так
obj:method(1, 2, 3)
же, какПочему локальная переменная? Потому что, как отмечали многие,
obj:method()
только индексы_ENV
можно получить один разobj
. Это обычно просто важно при рассмотрении скорости, но рассмотрим следующую ситуацию:Теперь представьте, что
__index
метаметод сделал больше, чем просто напечатал что-то. Представьте, что он увеличил счетчик, записал что-то в файл или удалил случайного пользователя из вашей базы данных. Есть большая разница между этим дважды или только один раз. В этом случае есть четкая разница междуobj.method(obj, etc)
иobj:method(etc)
.источник