Разница между. и: в Луа

Я путаюсь о различии между вызовами функций через . и через :

> 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

Что делает :?

Ответ 1

Двойник предназначен для реализации методов, которые передают self в качестве первого параметра. Поэтому x:bar(3,4) должен быть таким же, как x.bar(x,3,4).

Ответ 2

Для определения это точно так же, как указание self вручную - он даже произведет такой же байт-код при компиляции. То есть function object:method(arg1, arg2) совпадает с function object.method(self, arg1, arg2).

При использовании : почти то же самое, что и . - особый вид вызова будет использоваться внутренне, чтобы убедиться, что object и любые возможные побочные эффекты вычислений/доступа вычисляются только один раз. Вызов object:method(arg1, arg2) аналогичен object.method(object, arg1, arg2).