【问题标题】:How to check if a table element is nil如何检查表格元素是否为零
【发布时间】:2015-02-16 13:58:00
【问题描述】:

我有一个名为 frameActions 的表,在某些情况下它不能包含某些属性:

action = 'UP'
frameActions = {}
frameActions['UP'] = { a = 1, b = 2 }

如何检查表是否有特定的属性名称?

if frameActions[action].c ~= nil then
    -- do something
end

这种情况会抛出错误:attempt to index a nil value

【问题讨论】:

标签: lua conditional-statements null lua-table


【解决方案1】:

你可以使用一些 Lua 魔法并将Etan Reisner's comment 重写为

local E = {}
local my_val = ((frameActions or E).action or E).c
if my_val ~= nil then
    --your code here
end

此代码也检查 frameAction 是否为 nil。

解释:

这是 lua 评估第二行的方式(考虑 frameActions = {foo='bar'}):

(frameActions or E) --> {}, because frameAction is not nil or false and then will be take as result
(frameAction.action or E) --> E, because there is no 'action' key in frameAction table, so second 'or' argument is taken
E.c --> nil, because there is no 'c' key in empty table

那些“检查链”可能会更长。例如:

local E = {}
local my_val = ((((foo or E).bar or E).baz or E).xyz or E).abc
if my_val ~= nil then
    --code if foo['bar']['baz']['xyz']['abc'] is not nil
end

【讨论】:

  • 希望我可以通过提到这称为可选链接来加快下一次搜索。某些语言,如 javascript 和 C#,使用 .? 运算符支持这一点,因此这将是 foo?.bar?.baz?.xyz?.abc。似乎lua不直接支持。我们通过使用or 作为空合并运算符来解决此问题,并在每个步骤中提供空表作为后备。
【解决方案2】:

您可以使用元方法来检查您的代码是否正在尝试访问未定义的索引。它在lua wiki 上有详细记录。

使用以下代码,当 action 定义为未定义的索引时,将调用函数 check_main_index(t,k)check_sub_index(t,k) 函数在访问未定义的属性时被调用。

但是,如果 action 定义为“UP”,您编写的代码可以正常工作,并且仅当 action 定义为其他内容时才会抛出错误尝试索引 nil 值。 (使用 Lua 5.2 测试)。

action = 'UP'

local function check_main_index(t,k)
  print ( "main index : " .. k .. " does not exist" )
  return nil
end
local function check_sub_index(t,k)
  print ( "sub index : " .. k .. " does not exist" )
  return nil
end

frameActions = setmetatable({}, {__index = check_main_index})
frameActions['UP'] = setmetatable({ a = 1, b = 2 }, {__index = check_sub_index})

if frameActions[action].c ~= nil then
    print( "defined" )
else
    print( "not defined" )
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-13
    • 2014-06-24
    • 1970-01-01
    • 2012-03-18
    • 2012-08-28
    • 2019-08-16
    • 2016-03-13
    • 1970-01-01
    相关资源
    最近更新 更多