Lua:冒号,'自我'和函数定义与调用

Aub*_*e18 5 lua function self notation colon

我对定义/调用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
Run Code Online (Sandbox Code Playgroud)

令我困惑的是string.PatternSafe()在任何地方都没有引用'self',但代码似乎有效.

我还看到了一些在定义函数时使用冒号表示法的脚本,例如:

function foo:bar( param1 ) ... end
Run Code Online (Sandbox Code Playgroud)

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

  1. 如果使用冒号表示法定义函数,则会获得作为第一个参数插入的不可见"自"参数
  2. 如果使用冒号表示法调用函数,则将':'前面的对象插入到参数中(因此成为函数的第一个参数)
  3. 如果使用点表示法调用函数,那么即使使用冒号表示法定义它也不会将对象作为第一个参数/参数插入

如果我的假设是正确的,那就提出了另一个问题:确保正确调用函数的最佳方法是什么?

Eta*_*ner 5

你的假设都是正确的.

手册中的假设1 :

冒号语法用于定义方法,即具有隐式额外参数self的函数.因此,声明

 function t.a.b.c:f (params) body end
Run Code Online (Sandbox Code Playgroud)

是语法糖

 t.a.b.c.f = function (self, params) body end
Run Code Online (Sandbox Code Playgroud)

手册中的假设2 :

调用v:name(args)是v.name(v,args)的语法糖,除了v只计算一次.

假设3没有直接的手动部分,因为这只是普通的函数调用语法.

不过这是件事.self只是作为冒号分配的一部分使用的语法糖中给出的自动魔术名称.这不是必要的名字.无论名称是什么,第一个参数都是第一个参数.

所以在你的例子中:

function string.PatternSafe( str )
    return ( str:gsub( ".", pattern_escape_replacements ) );
end
Run Code Online (Sandbox Code Playgroud)

第一个参数是str这样的,当函数被调用时,char:PatternSafe()de-sugars(通过假设2)char.PatternSafe(char)只是char作为第一个参数传递给函数(正如我已经说过的那样str).