Lua:冒号符号、“自我”和函数定义与调用

2024-04-19

我对定义/调用 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. 如果使用点表示法调用函数,那么即使它是使用冒号表示法定义的,它也不会获得作为第一个参数/参数插入的对象

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


你的假设都是正确的。

假设1来自手册 http://www.lua.org/manual/5.1/manual.html#2.5.9:

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

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

是语法糖

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

假设2来自手册 http://www.lua.org/manual/5.1/manual.html#2.5.8:

调用 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).

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Lua:冒号符号、“自我”和函数定义与调用 的相关文章

  • 如何向 SQL 连接字符串添加自定义属性?

    我想在 SqlServer 连接字符串中添加一些自定义属性 如下所示 Integrated Security SSPI Extended Properties SomeAttr SomeValue Persist Security Info
  • 有什么方法可以让 C/C++ 程序在 main() 之前崩溃吗?

    有什么办法可以让程序在 main 之前崩溃吗 使用 gcc 您可以使用以下标记函数构造函数属性 http gcc gnu org onlinedocs gcc Function Attributes html index g t 0040c
  • 计算字符串向量中连续数字的函数

    我想创建一个函数 它接受至少 1 个元素的字符串对象并包含数字 2 到 5 并确定是否存在至少 N 长度的连续数字 其中 N 是实际数字值 如果是 则返回字符串 true 否则返回字符串 false 例如 Input 555123 Outp
  • Lua中有状态迭代器和无状态迭代器的区别

    Lua中无状态和有状态迭代器有什么区别 请详细解释一下 什么时候需要使用无状态 什么时候需要使用另一种 我需要例子来理解这个概念 首先让我们就一个定义达成一致 在 Lua 中 迭代器是function 类似对象 每次调用时都会返回序列中的下
  • 聚合函数在数据框中创建不需要的向量

    我在函数中创建数据帧时遇到了一个奇怪的问题 但是 在 data frame 之外使用相同的方法效果很好 这是基本函数 我用它来计算数据集的平均值 标准差和标准误差 aggregateX lt function formula dataset
  • JavaScript 函数默认参数[重复]

    这个问题在这里已经有答案了 const add a 1 b 1 c 1 gt a b c add 4 2 抛出未捕获的语法错误 意外的标记 如何调用该函数 使 b 默认为值 1 就拿undefined https developer moz
  • 函数内部变量的赋值会改变外部的赋值 - Python

    我从使用 Matlab 转向使用 Python 使用函数时的变量赋值让我感到困惑 我有一个代码如下 a 1 1 1 def keeps x y x y 1 2 return y def changes x y x y 1 2 return
  • 从类 T 获取函数名 (__func__) 和指向成员函数的指针 void(T::*pmf)()

    是否可以写一些f 接受类型的模板函数T和一个指向签名成员函数的指针void T pmf 作为 模板和 或函数 参数并返回const char 指向成员函数的 func 变量 或损坏的函数名称 EDIT 我被要求解释我的用例 我正在尝试编写一
  • SHA2 512 的改编给出了不正确的结果

    我正在尝试调整 SecureHashAlgorithm 的纯 Lua 实现here http lua users org wiki SecureHashAlgorithm对于 SHA2 512 而不是 SHA2 256 当我尝试使用改编时
  • TypeScript 接口函数属性:有什么区别?

    有人可以解释一下 为什么在这段代码中 对 Interface 类型常量的赋值有效 但对 Interface 类型常量的赋值会抛出错误 interface InterfaceA doSomething data object boolean
  • Scala 函数定义参数列表中不同的括号样式

    Scala 中以下两个函数定义有什么区别 1 def sum f Int gt Int a Int b Int Int code 2 def sum f Int gt Int a Int b Int Int code SBT 的控制台 RE
  • 如何编写从管道输入读取的 powershell 函数?

    SOLVED 以下是使用管道输入的函数 脚本的最简单示例 每个的行为都与通过管道传输到 echo cmdlet 相同 作为函数 Function Echo Pipe Begin Executes once before first item
  • 当函数参数与c中的const参数声明不匹配时编译的程序

    我有一段这样的代码 include
  • Verilog 中如何使用函数?

    在我的 FPGA Verilog 课程中 我的教授只是回顾了函数 他说在函数中 你可以按程序编写代码 然后 当您想要调用该函数时 您可以在always块中调用它 即 程序性地 也可以使用分配语句来调用它 对我来说 如何使用过程代码编写函数
  • 确定 PHP 到目前为止执行了多长时间

    我需要确定 PHP 函数到目前为止已经运行了多长时间 有哪些选项可以确定某些 PHP 代码的运行时间 我正在使用 zend 框架 Call microtime true 函数以毫秒分辨率获取当前时间
  • jquery 中的函数返回未定义[重复]

    这个问题在这里已经有答案了 我在 jquery 中调用的函数返回未定义 我检查了该函数 当我对其进行调试时 它返回正确的数据 function addToPlaylist component type add to pl value pl
  • 执行数组内的函数

    是否可以从数组内部执行匿名函数 也在数组内部定义 return execute function logic 或者我应该在外面定义它然后再调用它 从技术上讲 您可以将该函数括在括号中并像这样调用它 return function retur
  • C 链表销毁函数

    我正在尝试学习 C 和很多人一样 我对指针有点困惑 无论如何 我创建了一个递归函数来销毁我的链表 但是正如我调试的那样 当我从函数返回时 列表的头部不应该为空 所以我猜这是对指针的一些基本误解 这是函数 void destroy struc
  • 使用“const cv::Mat &”、“cv::Mat &”、“cv::Mat”或“const cv::Mat”作为函数参数的区别?

    我已经彻底搜索过 但没有找到一个简单的答案 传递 opencv 矩阵 cv Mat 作为函数的参数 我们传递一个智能指针 我们对函数内部的输入矩阵所做的任何更改也会改变函数范围之外的矩阵 我读到 通过将矩阵作为 const 引用传递 它不会
  • VB.NET - 类中的扩展函数?

    我正在尝试创建一个类库 其中包含将二进制整数转换为十进制的函数 反之亦然 这样我就可以将其导入到另一个项目中 而无需重写该函数 它工作得很好 这是课程的一部分 Public Class BinaryDenary Public Shared

随机推荐