Lua中的self、冒号和点号

本文介绍了Lua中的self概念,以及冒号和点号在方法定义和调用中的作用。冒号用于隐式传递self参数,而点号则需要显式传入。虽然两者功能相同,但冒号语法在指令执行上较点号略有优势,能节省一条指令,带来轻微的性能提升。

介绍

在lua中,表拥有一个标识:self。self类似于this指针,大多数面向对象的语言(比如C++、C#)都隐藏了这个机制,在编码时不需要显式地声明这个参数,就可以在方法内使用this。在lua中,提供了冒号操作符来隐藏self参数,比如:

local t = {a = 1, b = 2}
function t:Add()
	return (self.a + self.b)
end
print(t.Add())

冒号和点号实现同样的功能

冒号有两个作用:1.对于方法定义来说,提供了一个额外的隐藏形参(即self)。2.对于函数调用来说,会增加一个额外的实参(调用者本身)。

冒号其实是一种语法机制,点号与冒号可以完成同样的事情,例如:

--用冒号和点号实现同样的函数调用
--冒号实现
local tA = {a = 1, b = 2}
function tA:Add()
	return (self.a + self.b)
end
print(tA.Add())
--点号实现
local tB = {a = 1, b = 2}
function tB.Add(self)
	return (self.a + self.b)
end
print(tB.Add(tB))

冒号和点号的区别

拿上面那个等价的例子来说:
对于冒号实现,print(tA.Add())生成的指令如下:
在这里插入图片描述
可以看到有一个self指令,lua中的指令分为四类:IABC、iABx、iAsBx、iAx。self指令属于iABC类型,他会将表对象和函数拷贝到寄存器的连续两个位置中,寄存器索引由操作数A指定,表对象在寄存器中的位置由操作数B指定,函数的位置由操作数C指定。
在指令序列中,首先获取全局环境中的print函数,然后self指令做了两件事:获取表中的Add函数以及将表压入栈顶(冒号语法会将表自身作为实参传入给Add函数)。然后是两条函数调用指令CALL,分别调用Add函数与print函数。总共需要4条指令。

而对于点号实现,print(tB.Add(tB))生成的指令如下:
在这里插入图片描述
在指令序列中,首先和冒号一样获取全局环境中的print函数,然后获取表中的Add函数,然后通过MOVE指令将表压入栈顶。接着是同样的两个函数调用指令Call。总共需要5条指令。

总结

1.冒号和点号是lua中不同的语法机制,通过self可以实现一样的功能。
2.冒号语法比点号语法节省一条指令,可提供一点点性能优化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值