2016-04-08 83 views
2

錯誤比方說,我有一個巨大的表,是這樣的:Lua:嘗試索引一個零值;避免條件語句

test.test[1].testing.test.test_test 

表不能保證存在。這些表格都不包含它。我想只能夠做到:

if test.test[1].testing.test.test_test then 
    print("it exits!") 
end 

當然只是,這會給我一個「嘗試指數(一個零值)?」的錯誤,如果任何一個指標都沒有定義。這麼多次,我最終會做這樣的事情:

if test then 
    if test.test then 
     if test.test[1] then 
     if test.test[1].testing then -- and so on 

有沒有更好,更少繁瑣的方法來完成這個?

回答

2

您可以編寫一個函數,該函數使用一系列鍵來查找,並在找到該條目時執行所需的任何操作。這裏有一個例子:

function forindices(f, table, indices) 
    local entry = table 

    for _,idx in ipairs(indices) do 
    if type(entry) == 'table' and entry[idx] then 
     entry = entry[idx] 
    else 
     entry = nil 
     break 
    end 
    end 

    if entry then 
    f() 
    end 
end 

test = {test = {{testing = {test = {test_test = 5}}}}} 

-- prints "it exists" 
forindices(function() print("it exists") end, 
      test, 
      {"test", 1, "testing", "test", "test_test"}) 

-- doesn't print 
forindices(function() print("it exists") end, 
      test, 
      {"test", 1, "nope", "test", "test_test"}) 

順便說一句,函數式編程的概念,解決了這類問題是Maybe monad。你或許可以用Lua implementation of monads來解決這個問題,雖然它不會很好,因爲它沒有語法糖。

+0

非常整潔的解決方案,謝謝! –

2

您可避免通過設置爲零的__index元方法提高錯誤:

debug.setmetatable(nil, { __index=function() end }) 
print(test.test[1].testing.test.test_test) 
test = {test = {{testing = {test = {test_test = 5}}}}} 
print(test.test[1].testing.test.test_test) 

您還可以使用一個空表:

debug.setmetatable(nil, { __index={} }) 
相關問題