Lua:冒号符号,'self'和函数定义与调用 [英] Lua: colon notation, 'self' and function definition vs. call

查看:609
本文介绍了Lua:冒号符号,'self'和函数定义与调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我以为我会把头转过来直到我看到这个一段代码:

 函数string.PatternSafe(str)
return(str:gsub(。,pattern_escape_replacements ));
结束

函数string.Trim(s,char)
if char然后char = char:PatternSafe()else char =%send
return string .match(s,^.. char ..*(.-).. char ..* $)或s
end

有什么令我困惑的是,string.PatternSafe()并没有在任何地方引用'self',但代码看起来很有效。



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

  function foo:bar(param1)... end 

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


  1. 如果一个函数是用冒号表示法定义的,它将得到一个不可见的'self'参数作为第一个参数

  2. 如果使用冒号表示法调用一个函数,则将前面的':'对象插入参数中(所以变成函数的第一个参数)
  3. 如果使用点符号来调用函数,那么即使它使用冒号表示来定义,它也不会将该对象作为第一个参数/参数插入

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

解决方案

你的假设都是正确的。

假设1来自手册 b
$ b


冒号语法用于定义方法,也就是说,函数
有一个隐含的额外参数self。因此,语句

 函数tabc:f(params)body end 


是语法糖for

  tabcf = function(self, params)body end 


假设2来自手册


调用v:name(args)是v.name(v,args)的语法糖,只是v只计算一次。 b
假设3没有直接的手动部分,因为这只是普通的函数调用语法。



尽管如此, self 就是用作冒号分配一部分的语法sugar中给出的自动魔术名称。它不是必要的名称。第一个参数是第一个参数,无论名称如何。



所以在你的例子中:

 函数string.PatternSafe(str)
return(str:gsub(。,pattern_escape_replacements));
end

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


I'm getting terribly confused by the colon notation used when defining/calling Lua functions.

I thought I'd got my head round it until I saw this piece of code:

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

What's confusing me here is that string.PatternSafe() doesn't reference 'self' anywhere, yet the code seems to work.

I've also seen some scripts that use colon notation when defining the function, for example:

function foo:bar( param1 ) ... end

After several hours of googling I've still not managed to work out what precisely is happening in these two contexts. My current assumptions are as follows:

  1. If a function is defined using colon notation, it gets an invisible 'self' parameter inserted as first parameter
  2. If a function is called using colon notation, the object preceding ':' is inserted in to the arguments (so becomes the first parameter of the function)
  3. If a function is called using dot notation, then even if it was defined using colon notation it will not get the object inserted as first argument/parameter

If my assumptions are correct, that raises an additional question: What is the best way to ensure that the function was called properly?

解决方案

Your assumptions are all correct.

Assumption 1 from the manual:

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

Assumption 2 from the manual:

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

Assumption 3 doesn't have a direct manual section since that's just normal function call syntax.

Here's the thing though. self is just the auto-magic name given in the syntax sugar used as part of the colon assignment. It isn't a necessary name. The first argument is the first argument whatever the name happens to be.

So in your example:

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

the first argument is str so when the function is called as char:PatternSafe() is de-sugars (via assumption 2) to char.PatternSafe(char) which is just passing char to the function as the first argument (which, as I already said, is str).

这篇关于Lua:冒号符号,'self'和函数定义与调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆