【问题标题】:Arguments to require'd function get lost/disappear in Lua?要求函数的参数在 Lua 中丢失/消失?
【发布时间】:2019-01-27 00:50:04
【问题描述】:

虽然我并不真正了解 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,} 

所以,在myfunction 中对print(dump(indict)) 的响应,其中indict 是传递给myfunction 的参数,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”参数?

【问题讨论】:

    标签: lua


    【解决方案1】:

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

    因为你的模块定义是:

    function mymodule.myfunction(indict)
    

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

    要么将函数定义更改为

    function mymodule:myfunction(indict)
    

    如果你想保持调用mm:myfunction,或者调用函数mm.myfunction


    PiL book 中详细讨论了有关 OOP 概念的行为。

    冒号的作用是在a中增加一个额外的隐藏参数 方法定义并在方法调用中添加额外的参数。这 冒号只是一种句法工具,虽然很方便;那里 这不是什么新鲜事。

    【讨论】:

    • 非常感谢@hjpotter92 - 这正是我所缺少的,对冒号作用的理解:没想到它增加了一个额外的参数。
    猜你喜欢
    • 1970-01-01
    • 2017-04-06
    • 2017-02-23
    • 2011-12-12
    • 2021-03-06
    • 2019-12-09
    • 2012-11-13
    • 2019-01-28
    • 1970-01-01
    相关资源
    最近更新 更多