Jestem zdezorientowany różnicą między wywołaniami funkcji przez .
i przez:
> 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
Co to :
robi?
Odpowiedzi:
Dwukropek służy do implementowania metod, które są przekazywane
self
jako pierwszy parametr. Więcx:bar(3,4)
powinno być takie samo jakx.bar(x,3,4)
.źródło
self
obiektu, który przejdzie jako pierwszy parametr i jego wartość właściwości.object.method(object,args)
pobieranieobject
dwa razy, podczas gdyobject:method(arg)
pobieraobject
tylko raz. Jeśliobject
jest polem globalnym, upvalue lub tabeli, to:
jest szybsze niż.
..
nigdy nie jest szybszy niż:
.Z definicji jest to dokładnie to samo, co ręczne określanie siebie - przy kompilacji wygeneruje nawet ten sam kod bajtowy. To
function object:method(arg1, arg2)
jest to samo cofunction object.method(object, arg1, arg2)
.Używanie
:
jest prawie takie samo, jak.
- specjalny rodzaj połączenia będzie używany wewnętrznie, aby się upewnićobject
wszelkie możliwe skutki uboczne obliczeń / dostępu są obliczane tylko raz. Wobject:method(arg1, arg2)
innym przypadku dzwonienie jest takie samo jakobject.method(object, arg1, arg2)
.źródło
Aby być całkowicie precyzyjnym,
obj:method(1, 2, 3)
oznacza to samo, coDlaczego zmienna lokalna? Ponieważ, jak wielu zauważyło,
obj:method()
indeksy_ENV
można uzyskać tylko razobj
. Zwykle jest to ważne przy rozważaniu szybkości, ale rozważ taką sytuację:A teraz wyobraź sobie, że
__index
metametoda zrobiła coś więcej niż tylko wydrukowanie czegoś. Wyobraź sobie, że zwiększył licznik, zalogował coś do pliku lub usunął przypadkowego użytkownika z bazy danych. Istnieje duża różnica między zrobieniem tego dwa razy a tylko raz. W tym przypadku istnieje wyraźna różnica międzyobj.method(obj, etc)
iobj:method(etc)
.źródło