via .
와 via를 통한 함수 호출의 차이점에 대해 혼란 스럽습니다.:
> 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를 수동으로 지정하는 것과 정확히 동일합니다. 컴파일시 동일한 바이트 코드를 생성합니다. 즉와 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)
것은
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)
있습니다.