我对定义/调用 Lua 函数时使用的冒号表示法感到非常困惑。
我以为我已经明白了,直到我看到这段代码:
function string.PatternSafe( str )
return ( str:gsub( ".", pattern_escape_replacements ) );
end
function string.Trim( s, char )
if char then char = char:PatternSafe() else char = "%s" end
return string.match( s, "^" .. char .. "*(.-)" .. char .. "*$" ) or s
end
这里让我感到困惑的是 string.PatternSafe() 没有在任何地方引用“self”,但代码似乎可以工作。
我还看到一些脚本在定义函数时使用冒号表示法,例如:
function foo:bar( param1 ) ... end
经过几个小时的谷歌搜索后,我仍然无法弄清楚这两种情况下到底发生了什么。我目前的假设如下:
- 如果使用冒号符号定义函数,它将获得一个不可见的“self”参数作为第一个参数插入
- 如果使用冒号表示法调用函数,则“:”前面的对象将插入到参数中(因此成为函数的第一个参数)
- 如果使用点表示法调用函数,那么即使它是使用冒号表示法定义的,它也不会获得作为第一个参数/参数插入的对象
如果我的假设是正确的,就会引发一个额外的问题:确保正确调用该函数的最佳方法是什么?
你的假设都是正确的。
假设1来自手册 http://www.lua.org/manual/5.1/manual.html#2.5.9:
冒号语法用于定义方法,即函数
有一个隐式的额外参数 self.因此,声明
function t.a.b.c:f (params) body end
是语法糖
t.a.b.c.f = function (self, params) body end
假设2来自手册 http://www.lua.org/manual/5.1/manual.html#2.5.8:
调用 v:name(args) 是 v.name(v,args) 的语法糖,只不过 v 仅计算一次。
假设 3 没有直接的手册部分,因为这只是正常的函数调用语法。
但事情是这样的。self
只是语法糖中给出的自动魔术名称,用作冒号赋值的一部分。这不是一个必要的姓名。无论名称是什么,第一个参数都是第一个参数。
所以在你的例子中:
function string.PatternSafe( str )
return ( str:gsub( ".", pattern_escape_replacements ) );
end
第一个参数是str
所以当函数被称为char:PatternSafe()
脱糖(通过假设 2)char.PatternSafe(char)
这只是过去char
作为第一个参数的函数(正如我已经说过的,是str
).
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)