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
经过几个小时的谷歌搜索,我仍然无法弄清楚这两种情况下到底发生了什么。我目前的假设如下:
- 如果一个函数是使用冒号表示法定义的,它会得到一个不可见的 'self' 参数作为第一个参数插入
- 如果使用冒号表示法调用函数,“:”之前的对象将插入到参数中(因此成为函数的第一个参数)
- 如果使用点符号调用函数,那么即使它是使用冒号符号定义的,它也不会首先插入对象 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
)。
我对 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
经过几个小时的谷歌搜索,我仍然无法弄清楚这两种情况下到底发生了什么。我目前的假设如下:
- 如果一个函数是使用冒号表示法定义的,它会得到一个不可见的 'self' 参数作为第一个参数插入
- 如果使用冒号表示法调用函数,“:”之前的对象将插入到参数中(因此成为函数的第一个参数)
- 如果使用点符号调用函数,那么即使它是使用冒号符号定义的,它也不会首先插入对象 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
)。