问题描述
我试图遍历一个函数表,并一个一个地调用每个函数。 我不断收到“尝试访问字段/方法 NIL 值”的消息。 其中一些很明显,但其中一些让我感到困惑。
tests={}
function tests.test1()
print("test1 running\n")
end
function tests.test2()
print("test2 running\n")
end
function tests.test3()
print("test3 running\n")
end
print(tests)
-- why is tests.i() or tests:i not working?
for i,x in pairs(tests) do
print("x is")
print(x)
print("i is")
print(i)
--tests.i() -- attempt to call field i a NIL value
--tests.i(tests) -- ditto
--tests:i() -- attempt to call method i,a NIl value
--tests:i(tests) -- ditto
tests[i]() -- works!
--tests.x() -- attempt to call field x,a NIl value
--tests.x(tests) -- ditto
--tests:x() -- attempt to call method x,a NIL value
--tests[x]() -- attempt to call field ? a NIl value
end
--all these work
tests.test1(tests)
tests:test1()
tests.test2(tests)
tests:test2()
tests.test3(tests)
tests:test3()
为什么tests.i() 方法不起作用,或者tests.i(tests),如果它期待一个'self' 参数,在这种情况下为什么tests:i() 不起作用? 最后一点显示了它们在循环外调用时都可以工作,这使得它更难以理解。
解决方法
tests.i()
是 tests["i"]()
的语法糖。 tests:i()
是 tests["i"](tests)
的语法糖。
在你的循环中? for i,x in pairs(tests) do
、i
在各自的循环周期中分别为 "test1"
、"test2"
和 "test3"
。所以 tests[i]()
解析为 tests["test1"]()
等等,即 tests.test1()
请确保您了解 tests.i
是 tests["i"]
的缩写,而不是 tests[i]
!因此,在一种情况下,您使用字符串 tests
索引 "i"
而在第二种情况下,您将使用变量 i
的值对其进行索引,在您的情况下它是tests
。
在像您这样的循环中,值是函数,因此您可以简单地调用 x
而不是调用 tests[i]
btw。
除非您为其指定占位符,否则在调用 tests:test1()
时,插入的参数将被丢弃。
tests = {}
function tests.test1( a ) -- you can only use args you've accounted for
local a = a or ''
print( 'test1 running',a )
end
您还可以调用 x()
从循环中执行这些函数。
-- test i,test i. 1,2,3?
for i,x in pairs( tests ) do
print( string.format('i is "%s"',i ) )
print( 'x is',x )
x() -- same as calling tests["i"]()
end
tests:test1()
我是“test1”
x 是函数:0x1420f20
test1 正在运行
test1运行表:0x1421f10