为什么 Lua 的语法糖在这里不起作用(带冒号调用函数)?

我了解一些关于在 Lua 中调用函数语法糖的知识。

A = {}
function A.func(a) print(tostring(a)) end

我有一个上面的表 A。我可以像这样调用 A.func A.func(A),也可以像这样调用 A:func()

但是当我把 A 和 A.func 保存在表 B 中,然后尝试进行回调时,就会出现错误:“尝试调用一个空值(方法'v')

B = {}
B[A] = A.func

--调用 A.func
k,v = next(B)
k:v()--这里会报错
v(k)--这里不会报错

所以,我想知道当我使用语法糖时发生了什么?

原文链接 https://stackoverflow.com/questions/43648719

点赞
stackoverflow用户5331361
stackoverflow用户5331361

当你使用k:v()时,v并不是指上面的局部变量vk:v()语法告诉Lua在对象k中查找名为v的函数并执行它,将k作为第一个参数传递。

另一个例子可能更好地展示了这种行为:

k = {}
function k.v(a) print(tostring(a))end
local function v(a) print("local func called", a) end
k:v() -- 这种方法总是调用k.v函数,无论同名变量是否存在
2017-04-27 07:27:17
stackoverflow用户7900162
stackoverflow用户7900162

语法糖使这些指令等效:

> A["func"](A)
table: 009F7E58
> A.func(A)
table: 009F7E58
> A:func()
table: 009F7E58

因此,如果尝试执行命令 k:v(),它与 k["v"](k) 相同。但是您的表k没有记录“v”,它有记录“func”。所以您可以运行

> k["func"](k)
table: 009F7E58

或者

> v(k)
table: 009F7E58

或者

> k:func()
table: 009F7E58

正如您所看到的,变量“v”包含函数本身,而不是表k中函数的名称。但是如果想使用语法糖,您需要知道表中带有函数的记录的名称。

附言:是的,在您的示例中,“k”和“A”是同一张桌子(009F7E58)的名称。

2017-04-27 08:06:00