2011-12-08 3 views
5

내가 루아 새로운 그리고 난 같은 값을 저장 할 테이블 [DOH] 만들려면 : 그러나루아에 포인터와 같은 것이 있습니까?

parent.child[1].value = "whaterver" 
parent.child[2].value = "blah" 

을, 대부분이 하나의 아이, 그래서 같은 값에 액세스하는 것이 더 쉽습니다 이 :

parent.child.value 

가, 내가하는 방식으로, 제 값을 저장하고 싶은 일을 간단하게 만들 수

parent.child[1].value == parent.child.value 

그러나이 작업을 수행하는 것을 내가 두 번이 값을 저장해야 기억. 나는 그것을 할 수있는 방법이 있나요 있도록 :

parent.child.value points to parent.child[1].value 

메모리에 두 배의 값을 저장하지 않고?

추가 질문은 테이블의 메모리 양을 확인하는 방법입니다.

답변

10

하지만 값이 문자열로 저장, 그래서 두 곳이 아니라 테이블에서 참조 할 에 필요한 문자열입니다됩니다.

첫째, (부울, 숫자 및 라이트 유저 데이터를 제외한) 모든 유형이 참조가 있습니다 - t 테이블 인 경우 당신이 t2 = t을 수행 한 후 모두 tt2 메모리에 같은 테이블에 대한 참조입니다.

두 번째 것 - 문자열은 루아에서 인턴됩니다. 즉, "abc" 같은 문자열과 "ab".."c"의 결과는 모두 실제로 하나의 문자열입니다. Lua는 문자열에 대한 참조 만 저장합니다. 따라서 메모리에 대해 걱정할 필요가 없습니다. 한 번에 하나의 문자열 인스턴스 만 있습니다.

안전하게 parent.child.value = parent.child[1].value을 수행 할 수 있습니다. 테이블의 한 슬롯 (몇 바이트)에 대해서만 메모리를 사용합니다. 문자열은 복사되지 않고 참조 만됩니다.

+0

끝내 주셔서 감사합니다. – Krystian

3

(종종 객체로 사용되는) 루아 테이블은 복사되지 않고 참조됩니다. (내부적으로 포인터가 그들에게 사용)

+0

하지만 값은 문자열로 저장되므로 테이블이 아닌 두 위치 모두에서 참조해야하는 문자열입니다. 이 경우에도 귀하의 답변이 유효합니까? – Krystian

+0

나는 그것이 그렇다고 생각한다. –

+0

지금 적절한 질문은 테이블의 메모리 크기를 확인하는 것입니다? 이렇게하면 확실한 질문에 답할 수 있습니다. – Krystian

3

이 사용 메타 테이블을위한 좋은 응용 프로그램입니다 : 인덱스가 ('값'처럼), 그것은의 __index의 값의 표에서 찾아 지는가 자식 테이블에서 발견되지 않는 경우

parent={ 
    child={ 
     {value="whatever"}, 
     {value="blah"} 
    } 
} 
setmetatable(parent.child,{__index=parent.child[1]}) 

메타 테이블 (이 경우에는 자식의 첫 번째 요소)

print(parent.child.value) -- prints whatever 
parent.child[1]=nil --remove first child 
print(parent.child.value) -- still prints whatever! 

메타 테이블이 수확되는 것을 방지, 첫 번째 자식 테이블에 대한 참조를 유지하기 때문이다 :

지금 우리가 folows로 볼 수 있습니다 위의 코드에 문제가있는 것입니다. 이런 종류의 문제를 해결하려면 A) 메타 테이블을 약한 테이블로 만들거나 B) __index 필드를 함수를 테이블로 참조하는 대신 함수로 만듭니다. 당신이 메타 테이블에 읽어 정말 관심이 있다면

-- A) 
setmetatable(parent.child, setmetatable(
    {__index=parent.child[1]} -- metatable for the child table 
    {__mode='v'}-- metatable for the metatable, making it have weak keys 
    ) 
) 
parent.child[1]=nil 
print(parent.child.value) --returns nil 
parent.child[1]={value='foo'} 
print(parent.child.value) -- prints nil, the metatable references to a non-existant table. 
-- hence solution B) 

setmetatable(parent.child, {__index=function(t,k) return parent.child[1][k]}) 
print(parent.child.value) -- 'whatever' 
parent.child[1]=nil 
print(parent.child.value) -- nil 
parent.child[1]={value='foobar' 
print(parent.child.value) -- foobar, now it will always refer to the table at child[1], even when it changes. 

Programming in Lua, chapter 13chapter 17 (weak tables)을 읽어보세요.Lua-Users wiki on MetaMethods도 흥미로울 것입니다.

+0

감사합니다. 나는 여전히 루아에서 객체로서 setmetatable과 using 테이블을 사용하는 데 어려움을 겪고있다. 이 구조체는 읽기 전용으로 사용되며 수정할 필요가 없으므로 실제로 잘 작동합니다. 정말 고마워. 고마워. – Krystian

0

C 배열의 경우 parent.childparent.child[0]은 포인터 산술로 인해 동일합니다. 당신이 정말로 스타일을 좋아하기 때문에 C의 가장 오류가 발생하기 쉽고 혼란스럽고 중복되는 기능 중 하나를 에뮬레이션하려고해서는 안됩니다.

관련 문제