我对定义/调用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
经过几个小时的谷歌搜索后,我仍然无法弄清楚在这两种情况下究竟发生了什么。我目前的假设如下:
如果我的假设是正确的,那就提出了另一个问题:确保正确调用函数的最佳方法是什么?
答案 0 :(得分:5)
您的假设都是正确的。
来自the manual的假设1:
冒号语法用于定义方法,即函数 有一个隐含的额外参数self。因此,声明
function t.a.b.c:f (params) body end
是
的语法糖t.a.b.c.f = function (self, params) body end
来自the manual的假设2:
调用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
)。