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

Why lua's syntax sugar not work here(call function with colon)?

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

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

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

但是当我把A和A.func保存在一个tableB中,然后尝试回调。发生错误,即“试图调用一个零值(方法'v')

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

--call A.func
k,v = next(B)
k:v()--error happened here
v(k)--no error occurred

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

当你使用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() -- this method always call k.v function 
      -- no matter that variable with same name exists

语法糖使这些命令等价

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

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

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

> v(k)
table: 009F7E58

> k:func()
table: 009F7E58

如您所见,变量 "v" 包含函数本身,而不是 table k 中的函数名称。但是如果想使用语法糖,你需要知道 table.

中具有函数的记录的名称

P.S。是的,在您的示例中 "k" 和 "A" 是相同的名称 table (009F7E58).