의 차이점 : : 루아


174

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

뭐라고입니다 :거야?


답변:


237

콜론은 self첫 번째 매개 변수로 전달 되는 메소드를 구현하기위한 것 입니다. 따라서 x:bar(3,4)와 동일해야합니다 x.bar(x,3,4).


55
아 .. 그래서 그것은 객체 지향 구문 설탕입니다.
Jason S

7
바로 그거죠. 전체 참조 매뉴얼에서 이들이 언급 한 유일한 문제점은 "콜론 구문은 메소드, 즉 내재 된 추가 매개 변수 자체를 갖는 함수를 정의하는 데 사용됩니다."입니다. (5.0 매뉴얼, pdf 19 페이지 하단)
BMitch

2
우 아아 ... 공식 문서가 어디에 있는지 물어 보려고했지만 당신이 나를 이겼습니다. 잘 했어. :-)
Jason S

1
@keyle self개체 에 따라 첫 번째 매개 변수 및 속성 값이됩니다.
Hydroper

8
가상 머신이 한 번만 검색하기 때문에 호출하는 객체가 로컬이 아닌 경우 @keyle Colon 구문이 약간 더 빠릅니다. 기본적으로 같은 구문 점 object.method(object,args)취득을 object두 번하는 동안 object:method(arg)검색하여 object한 번만. 경우 object글로벌, upvalue 또는 테이블 필드가 다음 :보다 빠른입니다 .. .보다 빠르지 않습니다 :.
negamartin

28

정의를 위해 self를 수동으로 지정하는 것과 정확히 동일합니다. 컴파일시 동일한 바이트 코드를 생성합니다. 즉와 function object:method(arg1, arg2)같습니다 function object.method(object, arg1, arg2).

사용시 :거의 동일합니다. .내부에서 특수한 종류의 호출을 사용 object하여 계산 / 접근의 가능한 부작용이 한 번만 계산되도록합니다. object:method(arg1, arg2)그렇지 않으면 호출은와 동일합니다 object.method(object, arg1, arg2).


21

완전히 정확한 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)있습니다.


당신은 정말로 그런 것들에 대해 걱정해서는 안됩니다. 필요한 경우 아키텍처에 끔찍한 문제가 있습니다.
발은 모니 티 복원 모니카

2
나는 그것이 다른 방향이라고 말하고 싶습니다. 좋은 코드는 관련없는 코드의 구현 세부 사항에 대해 어떤 가정도해서는 안됩니다. 함수 호출은 메모 화되거나 메모리 화되지 않을 수 있습니다. 즉, 필요 이상으로 자주 호출하는 것이 좋습니다.
DarkWiiPlayer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.