Lua 中传递给 require 函数的参数会丢失或消失吗?

虽然我不太熟悉 Lua,但这是一种非常意外和奇怪的行为。

假设我有一个名为 my_module.lua 的文件:

local function dump(o) -- SO:9168058
  if type(o) == 'table' then
    local s = '{ '
    for k,v in pairs(o) do
       if type(k) ~= 'number' then k = '"'..k..'"' end
       s = s .. '['..k..'] = ' .. dump(v) .. ','
    end
    return s .. '} '
  else
    return tostring(o)
  end
end

local mymodule = {}

function mymodule.myfunction(indict)
  print(dump(indict))
end

return mymodule

现在我运行这个命令:

lua5.3 -e "mm=require('my_module'); mm:myfunction({aa=12})"

理论上这应该很简单 - 我“导入”模块,并在其中调用一个带有一个对象参数的函数(即表/关联数组/字典 {aa=12})。然后我只是试图从函数内部打印此参数。但是我得到了这个结果:

$ lua5.3 -e "mm=require('my_module'); mm:myfunction({aa=12})"
{ ["myfunction"] = function: 0x5619aeddf770,}

所以,当 indict 是传递给 myfunction 的参数时,在 myfunction 内部运行 print(dump(indict)) 时,Lua 打印出了... "myfunction" ????!

我甚至无法理解这一点 - 这怎么可能发生?

我该如何将对象作为参数传递给函数,以便在函数内部打印参数时打印该参数的对象 - 而不是函数本身?

顺便说一下,即使我只传递一个数字,比如:

lua5.3 -e "mm=require('my_module'); mm:myfunction(42)"

编辑:进行了一些调试 - 所以这样写:

function mymodule.myfunction(indict)
  print(indict)
  print(dump(indict))
end

...当传递数字参数时,我得到了以下输出:

$ lua5.3 -e "mm=require('my_module'); mm:myfunction(42)"
table: 0x55f15a7a07a0
{ ["myfunction"] = function: 0x55f15a7a07e0,}

...所以它根本没有看到这个数字,但这个函数看到自己作为第一个参数。

这让我想起了 Python 类中,您必须将方法编写为具有“self”作为第一个参数的函数,因此我尝试了这个:

function mymodule.myfunction(self, indict)
  print("self", self, "indict", indict)
  print(dump(indict))
end

...它会打印出以下信息:

$ lua5.3 -e "mm=require('my_module'); mm:myfunction(42)"
self    table: 0x560510b5a7d0   indict  42
42

...或者,如果传递对象:

$ lua5.3 -e "mm=require('my_module'); mm:myfunction({aa=12})"
self    table: 0x55d51c9d5800   indict  table: 0x55d51c9d5880
{ ["aa"] = 12,}

...这更像是它...

有人能解释这是从哪里来的吗?为什么我需要在这种情况下添加“self”参数?

点赞
用户1190388
用户1190388

在 lua 中,调用 a:b(x) 将对象 a 作为第一个( self)参数传递给函数 b

由于您的模块定义如下:

function mymodule.myfunction(indict)

并且调用语句是 mm:myfunction,因此将对象 / 表 mm 作为第一个参数传递(这里是indict)。

如果想保留调用 mm:myfunction 格式,可以更改函数定义为:

function mymodule:myfunction(indict)

或者以 mm.myfunction 的方式调用该函数。


有关 OOP 概念的详细行为讨论在 PiL 书籍 中。

冒号的效果是在方法定义中添加一个隐藏参数并在方法调用中添加一个额外的参数。冒号只是一种语法便利,尽管它很方便,但这里并没有真正的新东西。

2019-01-27 00:58:56