2014-01-23 1 views
0

는 metatable에 약간의 문제가 있습니다. 이건 내 간단한 메타 테이블이다 :메타 테이블의 부분

mt.math:floor() return math.floor(self:get()) end 
mt.effect:show(args) onMapShowEffect(self:get(), {x = x + (args[1] ~= nil or 0), ...) end 
mt.effect:get() return getCurrentPos() end 

어떤 아이디어 : 각자가 같은 몇 가지 자신의 방법이있다

mt.math 
mt.effect 

:

local mt = {} 
function mt:add(n) 
    return setmetatable({n = n}, {__index = mt}) 
end 

function mt:get() return self.n end 

지금은 같은 일부 부문을 추가 할

?

확인을 클릭하여 내 세부 사항을 공유하십시오. 코드 위

Player = {} 
function Player:add(this) 
    return setmetatable({this = this}, {__index = Player}) 
end 

Player:get() return self.this end 

function enterToGame(player1, player2) 
    local p1 = Player:add(player1) 
    local p2 = Player:add(player2) 
    print(p1:get()) -- ID1 
    print(p2:get()) -- ID2 

가 지금은 테이블 플레이어에 대한 몇 가지 유용하게 방법 (함수)를 만들려면이 예에서 완벽하게 작동합니다. 좀 더 유연하게 만들고 싶기 때문에 수업을 위해 나누고 싶습니다. 예 :

Player.info = { 
    id = function() return Player:get() end, 
} 
Player.pos = { 
    get = function() return getPosition(Player:get()) end, 
    set = function(args) setPosition(Player:get(), args) end, 
} 
Player.speed = { 
    get = function() return getSpeed(Player:get()) end, 
    set = function(value) setSpeed(value) end, 
    improve = function(value) setSpeed(Player.speed.get() + value) end, 
} 

하지만 내가 원하는 것을 정확하게 작동하지 :

function enterToGame(player1, player2) 
    local p1 = Player:add(player1) 
    local p2 = Player:add(player2) 
    print(p1:get()) -- ID1 
    print(p2:get()) -- ID2 
    print(p1.info.id()) -- ID2 instead of ID1 
    print(p2.info.id()) -- ID2 

내가 넣어

플레이어 : 수() 마지막 객체 선언의 반환 나의 방법이다. (MT)은 mt.math에 대한 메타 테이블이기 때문에

+0

정확하게 이해할 수있을 지 모르겠지만 내부 함수에서'self'는'mt.math' /'mt.effect' 테이블이 될 것이고 최상위'mt' 테이블은 그렇지 않을 것입니다 그건 당신에게 명확하지 않았습니다. –

+0

mt를 호출 할 수있는 방법이 있습니까? – Synchro

+0

mt 테이블에'__call' 메타 메소드를 주면 호출 할 수 있습니다. 그래도 그게 당신의 질문에 어떻게 관련이 있는지 모르겠습니다. –

답변

0

는 진술 내용에 따라, 당신은

mt.math = mt:add(123) 

을 할 경우는 mt:get() 필요하지 않습니다. 그런 다음

mt.math.floor = function(self) return math.floor(self.n) end 

이 예상대로 작동합니다. 예를 들어,

print(mt.math:floor()) 

인쇄 123

편집 1 : 그래서 지금은 당신이 뭘 하려는지에 대한 이해를 가지고 : 일반적으로 당신은 콜론

p1:id() 
p1:getPos() 
p1:setPos() 
p1:getSpeed() 
p1:improveSpeed() 

주의 할 것 , 이것은 중요합니다. 그래서 각 메소드는 첫 번째 매개 변수로 "self"를 얻습니다. 따라서 위의 예제에서 p1을 처리 할 테이블 인스턴스가 주어집니다. 대신 이러한 방법 등 p1.pos을 p1.info 가리키는하지만 그 하위 테이블이 컨테이너 테이블 (P1)에 대한 지식이없는 자기를 얻을 것이다 그래서

p1.info:id() 
p1.pos:get() 
p1.pos:set() 
p1.speed:improve() 
p1.speed:get() 

그룹 방법으로합니다. info 및 pos 테이블은 Player 클래스에 있습니다. 플레이어의 모든 인스턴스에서 공유됩니다 (p1, p2 등). 난 정말이 같은 폐쇄를 사용하지의 생각처럼 안,

function Player:add(player) 
    local pN= setmetatable({n = player, info={}, pos={}}, {__index = Player}) 
    pN.info.id = function() return pN.n end 
    pN.pos.set = function(x) return setPosition(pN, x) end 
    return pN 
end 

는 그런 다음

> p1=mt:add(player1) 
> p2=mt:add(player2) 
> print(player1) 
table: 0024D390 
> print(p1.info.id()) 
table: 0024D390 
> print(player2) 
table: 0024D250 
> print(p2.info.id()) 
table: 0024D250 

말했다 모두를 얻을 : 당신은 비 - 공유 정보와 POS 테이블을해야 모든 것이 플레이어에 있지 않을 수도 있기 때문에 아마도 거기에 문제가 있습니다.

+0

정확히는 아닙니다. 나는 그것을 사용하기 전에 함수를 만들고 싶다. 귀하의 경우에는 먼저 mt : add()를 mt.math에 할당하고 mt.math.floor 함수를 생성해야합니다. 자세한 내용은 내 문제를 수정했습니다. – Synchro

+0

@ user3225882 OK 새 정보를 기반으로 대답을 확장했습니다. 지금하고있는 일을 이해하고 있다고 생각합니다. – Schollii

관련 문제