2014-05-21 10 views
3

깊게 중첩 된 표 안에있는 입력란의 경우 (예 : text.title.1.font). 테이블의 수준이하는 경우깊이 중첩 된 테이블에 오류없이 액세스합니까?

if text.title.1.font then ... end 

를 사용하는 경우에도이 "인덱스 글로벌 '텍스트'에 대한 시도 (nil의 값)"와 같은 오류가 발생 것이 실제로 존재한다. 물론 테이블의 각 레벨의 존재를 확인하려고 시도 할 수도 있지만 다소 번거로운 것처럼 보입니다. 같은 개체를 참조 할 때 오류를 트리거하는 대신 값이 될 수 있으므로 안전하고 예쁘게 처리 할 수 ​​있는지 궁금합니다.

+1

'debug.setmetatable (전무 {__index = 함수() 단부})' –

+1

Autotables/Autovivification (참조 [1] (http://stackoverflow.com/a/21287623/1244588) 또는 [2 ] (http://lua-users.org/wiki/AutomagicTables))도 대부분의 경우 꽤 잘 작동하지만'nil' 메타 테이블을 수정하거나 디버그 라이브러리를 요구하지 않습니다. 그런데'1'은'.' 또는':'구문에 유효하지 않습니다. 색인이 붙은 색인은 문자 ('a-Z') 나 밑줄 문자로 시작해야합니다. ([3] (http://www.lua.org/manual/5.2/manual.html#3.1)) – dualed

답변

1

Egor의 제안 debug.setmetatable(nil, {__index = function()end})은 가장 쉽게 적용 할 수 있습니다. 어휘 적으로 범위가 지정되지 않으므로 일단 켜져 있으면 꺼질 때까지 "on"상태가되어 코드의 다른 부분에서 의도하지 않은 결과가 발생할 수 있습니다. 토론 및 다른 대안에 대해서는 this thread을 참조하십시오.

또한 text.title.1.fonttext.title[1].font 또는 text.title['1'].font이어야하며이 둘은 동일하지 않습니다.

또 다른, 좀 더 자세한하지만, 여전히 가능한 대안은 다음과 같습니다 테이블 테이블해야 필드 그중 어떤

if (((text or {}).title or {})[1] or {}).font then ... end 
1

버그를 많이 초대하지 않는이 작업을 수행하는 방법을 명시 적 루아에게 기본적으로. 메타 테이블로이 작업을 수행 할 수 있습니다. 다음은 예제이지만 실제로 테이블을 구성하는 방법에 따라 사용자 지정해야합니다.

-- This metatable is intended to catch bugs by keeping default tables empty. 
local default_mt = { 
    __newindex = 
    function() 
     error(
    'This is a default table. You have to make nested tables the old-fashioned way.') 
    end 
} 

local number_mt = { 
    __index = 
    function(self, key) 
     if type(key) == 'number' then 
    return setmetatable({}, default_mt) 
     end 
    end 
} 

local default_number_mt = { 
    __index = number_mt.__index, 
    __newindex = default_mt.__newindex 
} 

local title_mt = {__index = {title = setmetatable({}, default_number_mt)}} 

local text = setmetatable({}, title_mt) 

print(text.title[1].font)