Разница между ними. и: в Луа
Я запутался в разнице между вызовами функций через . и через :
> 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
что такое : делаешь ?
3 ответа:
двоеточие предназначено для реализации методов, которые проходят
selfв качестве первого параметра. Так чтоx:bar(3,4)должно быть то же самое, что иx.bar(x,3,4).
по определению ровно то же самое, что указать self вручную - он даже будет производить тот же байт-код при компиляции. То есть
function object:method(arg1, arg2)такой же, какfunction object.method(self, arg1, arg2).использовать
:и почти то же самое, что.- специальный вид вызова будет использоваться внутри, чтобы убедитьсяobjectи любые возможные побочные эффекты вычислений / доступа рассчитываются только один раз. Звонюobject:method(arg1, arg2)в противном случае то же самое, чтоobject.method(object, arg1, arg2).
если быть совсем точным,
obj:method(1, 2, 3)это то же самое, чтоdo local _obj = obj _obj.method(_obj, 1, 2, 3) endпочему локальная переменная? Потому что, как указывали многие,
obj:method()только индексы_ENVпослеobj. Это обычно просто важно при рассмотрении скорости, но рассмотрим эту ситуацию:local tab do local obj_local = { method = function(self, n) print n end } tab = setmetatable({}, {__index = function(idx) print "Accessing "..idx if idx=="obj" then return obj_local end end}) end tab.obj.method(tab.obj, 20) --> Accessing obj --> Accessing obj --> 20 tab.obj:method(10) --> Accessing obj --> 10теперь представьте
__indexметаметод сделал больше, чем просто что-то печатая. Представьте, что он увеличил счетчик, записал что-то в файл или удалил случайного пользователя из вашей базы данных. Есть большая разница между тем, чтобы сделать это дважды или только один раз. В этом случае есть явная разница междуobj.method(obj, etc)иobj:method(etc).