, 당신은 일반적으로 호출 할 수 없습니다 테이블 : 그냥 myclass.lua
으로 업데이트합니다. 예를 들어,이 코드는 "local 't (테이블 값)을 호출하려고 시도합니다."라는 오류를 생성합니다.
local t = {}
t()
그러나 메타 테이블을 사용하여이 작업을 수행하는 방법이 있습니다.
local hello = {}
local mt = {} -- The metatable
mt.__call = function()
print("Hello!")
end
setmetatable(hello, mt)
hello() -- prints "Hello!"
함수처럼 테이블을 호출하려고하면 루아는 먼저 테이블에 메타 테이블이 있는지 확인합니다. 존재하면 해당 메타 테이블의 __call
속성에서 함수를 호출하려고 시도합니다. __call
함수의 첫 번째 인수는 테이블 자체이며 후속 인수는 테이블이 함수로 호출되었을 때 전달 된 인수입니다. 테이블에 메타 테이블이 없거나 메타 테이블에 __call
함수가 없으면 "로컬 't'호출 시도가 발생했습니다."오류가 발생합니다.
- 당신은
__init
대신 __call
를 사용하려고 : 귀하의 예제 코드는 세 가지 문제가 있습니다. 루아에는 __init
메타 메소드가 없습니다.
__call
에는 사용중인 매개 변수와 다른 매개 변수가 사용됩니다. __call
함수의 첫 번째 매개 변수는 테이블 자체입니다. function MyClass.__call(self, tab)
을 사용하거나매개 변수를 암시 적으로 추가하는 콜론 구문 function MyClass:__call(tab)
을 사용할 수 있습니다. 이 두 구문은 기능적으로 동일합니다.
MyClass
테이블에 대한 메타 테이블을 설정하지 않았습니다. MyClass의 객체에 대한 메타 테이블을 설정하는 중이지만 그것이 메타 테이블이 MyClass 자체에 자동으로 설정된다는 것을 의미하지는 않습니다.
이 문제를 해결하려면 다음과 같이 뭔가를 할 수 :
는
local MyClass = {}
setmetatable(MyClass, MyClass)
MyClass.__index = MyClass
function MyClass:__call(tab)
local obj = {}
obj.tab = tab or {}
setmetatable(obj, MyClass)
return obj
end
return MyClass
이 MyClass에 완벽하게 유효한 루아하는 메타 테이블, 그 자체를 사용하여 설정합니다.
메타 테이블 시스템은 매우 유연하며 사용자가 원하는 모든 클래스/객체 체계를 가질 수 있습니다. 예를 들어 원한다면 모든 것을 인라인으로 처리 할 수 있습니다.
local MyClass = {}
setmetatable(MyClass, {
__call = function (class, tab)
local obj = {}
obj.tab = tab or {}
setmetatable(obj, {
__index = MyClass
})
return obj
end
})
return MyClass
뿐만 아니라 간결되는 ,이 또한 클래스 테이블에 액세스 할 수있는 경우 사람들이 클래스의 메타 메소드를 변경할 수있는 장점이있다.
테이블의 메타 테이블을 자체로 설정하고 __index 메타 메서드를 자체로 설정하면 약간의 단점이 있습니다 (큰 단점). 'local obj = MyClass {1, 2, 3}'는 실제로이 코드에서 잘 작동하지만,'obj.foo'를 인덱스하려고하면'foo'가'obj'에 존재하지 않는다고 봅니다. 'MyClass' 테이블에서'foo'를 검사합니다. obj의 __index를 설정합니다. 'MyClass'에서'foo'를 찾지 못하기 때문에'MyClass'의 __index를 봅니다. 이것은'MyClass'입니다. 루아는 이것이 무한 루프라는 것을 감지 할 정도로 똑똑하기 때문에 오류가 발생합니다. –