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

function lua

29618 просмотра

3 ответа

112497 Репутация автора

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

> 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

Что :делает?

Автор: Jason S Источник Размещён: 06.02.2011 02:43

Ответы (3)


219 плюса

89355 Репутация автора

Решение

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

Автор: BMitch Размещён: 06.02.2011 02:55

25 плюса

17699 Репутация автора

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

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

Автор: Oleg V. Volkov Размещён: 04.10.2013 03:58

18 плюса

2865 Репутация автора

Чтобы быть полностью точным, так 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).

Автор: DarkWiiPlayer Размещён: 17.08.2018 11:32
Вопросы из категории :
32x32