Lua:冒号符号,'self'和函数定义与调用

Lua: colon notation, 'self' and function definition vs. call

我对 defining/calling 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

经过几个小时的谷歌搜索,我仍然无法弄清楚这两种情况下到底发生了什么。我目前的假设如下:

  1. 如果一个函数是使用冒号表示法定义的,它会得到一个不可见的 'self' 参数作为第一个参数插入
  2. 如果使用冒号表示法调用函数,“:”之前的对象将插入到参数中(因此成为函数的第一个参数)
  3. 如果使用点符号调用函数,那么即使它是使用冒号符号定义的,它也不会首先插入对象 argument/parameter

如果我的假设是正确的,那会引发另一个问题:确保函数被正确调用的最佳方法是什么?

你的假设都是正确的。

来自 the manual 的假设 1:

The colon syntax is used for defining methods, that is, functions that have an implicit extra parameter self. Thus, the statement

 function t.a.b.c:f (params) body end

is syntactic sugar for

 t.a.b.c.f = function (self, params) body end

来自 the manual 的假设 2:

A call v:name(args) is syntactic sugar for v.name(v,args), except that v is evaluated only once.

假设 3 没有直接的手册部分,因为那只是正常的函数调用语法。

事情是这样的。 self 只是语法糖中给出的自动魔术名称,用作冒号赋值的一部分。这不是一个 必要的 名称。第一个参数是第一个参数,不管名称是什么。

所以在你的例子中:

function string.PatternSafe( str )
    return ( str:gsub( ".", pattern_escape_replacements ) );
end

第一个参数是 str 所以当函数被调用时 char:PatternSafe() 是脱糖(通过假设 2)到 char.PatternSafe(char) 只是传递 char作为第一个参数的函数(正如我已经说过的,是 str)。