lua - 要求函数的参数在 Lua 中丢失/消失?
问题描述
虽然我并不真正了解 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,}
因此,对print(dump(indict))
inside的响应,传递给的参数在myfunction
哪里,Lua 打印 .... ????!indict
myfunction
"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,}
……嗯,这更像是……
谁能解释这是从哪里来的 - 为什么在这种情况下我需要添加一个“自我”论点?
解决方案
在 lua 中,调用a:b(x)
将对象的引用a
作为第一个 ( self
) 参数传递给函数b
。
由于您的模块定义是:
function mymodule.myfunction(indict)
并且调用语句是mm:myfunction
,对象/表mm
作为第一个参数传递(这里是indict
)。
将函数定义更改为
function mymodule:myfunction(indict)
如果你想保持 call like mm:myfunction
,或者调用函数 as mm.myfunction
。
该行为在有关 OOP 概念的PiL 书中进行了详细讨论。
冒号的作用是在方法定义中添加一个额外的隐藏参数,并在方法调用中添加一个额外的参数。冒号只是一种句法工具,虽然很方便;这里没有什么新东西。
推荐阅读
- swiper - 在 Swiper JS 中使用下一个/上一个按钮控制幻灯片的数量
- c - 尝试在我的案例陈述中放置我的错误陈述
- android - 'kotlin-android-extensions' 已弃用
- python - 如何按需要打印到 .csv 的列对该列表进行排序
- scala - 在scalatest中,如何在测试结果中显示完全差异?
- javascript - Vue/Nuxt 是否有适当的模式来加载和编辑组件数据而无需生命周期挂钩
- sql - 如何使用持久化和右()执行列更改?
- kubernetes - 如何使用 Terraform 在 GKE 中设置非默认服务帐户?
- android - Navigation resets when switching fragments
- reactjs - 从 Apollo 查询设置初始反应上下文状态