找回密码
 立即注册
查看: 344|回复: 4

Lua中的self

[复制链接]
发表于 2022-4-9 10:55 | 显示全部楼层 |阅读模式
在lua中,表拥有一个标识:self。self类似于this指针,大多数面向对象语言都隐藏了这个机制,在编码时不需要显示的声明这个参数,就可以在方法内使用this(例如C++和C#)。在lua中,提供了冒号操作符来隐藏这个参数,例如:
local t = {a = 1, b = 2}
function t:Add()
    return (self.a + self.b)
end

print(t:Add())冒号的作用有两个:1. 对于方法定义来说,会增加一个额外的隐藏形参(self);2. 对于方法调用来说,会增加一个额外的实参(表自身)
冒号只是一种语法机制,提供的是便利性,并没有引入任何新的东西。使用冒号完成的事情,都可以使用点语法来完成。看下面的例子:
local t = {a = 1, b = 2}
function t:Add()
    return (self.a + self.b)
end
function t.Sub(self)
    return (self.a - self.b)
end

print(t.Add(t))
print(t:Sub())既然点和冒号都可以完成同样的事情,那么除了便利性之外,还有没有其他区别呢?有,lua为冒号提供了独有的指令:SELF
我们以下面A和B两个等价的例子来说明:
-------------------------------------
---Sample A
local tA = {a = 1, b = 2}
function tA.Add(self)
    return (self.a + self.b)
end
print(tA.Add(tA))

-------------------------------------
---Sample B
local tB = {a = 1, b = 2}
function tB:Add()
    return (self.a + self.b)
end
print(tB:Add())对于例A,"print(tA.Add(tA))"生成的指令如下所示:


在指令序列中,首先获取全局环境中的print函数,接着获取tA表中的Add函数,然后通过MOVE指令将tA压入栈顶,因为tA将作为参数传入给Add函数。接着就是两条函数调用指令CALL,分别调用Add函数与print函数。总共需要5条指令。


SELF指令

在看例B生成的指令之前,我们先来了解下SELF指令。lua中的指令分为四类:iABC、iABx、iAsBx、iAx(这里我们不深入讨论指令,感兴趣的读者可以自行查阅资料 :))。SELF指令属于iABC类型,它会将表对象和函数拷贝到寄存器的连续两个位置中,寄存器索引由操作数A指定,表对象在寄存器中的位置由操作数B指定,操作数C指定了函数的位置(寄存器中或者常量表中)。
然后我们来看例B,"print(tB:Add())"生成的指令如下所示:


在指令序列中,首先获取全局环境中的print函数,接着SELF指令做了两件事情:获取tB表中的Add函数以及将tB压入栈顶,由此可见冒号语法会将表自身作为实参传入给Add函数。接着还是两条函数调用指令CALL,分别调用Add函数与print函数。总共需要4条指令。


总结

通过以上分析,可以了解到冒号语法除了提供便利性之外,还会为我们节省一条指令。虽然一条指令的开销几乎可以忽略不计,但性能优化不就是这样一点一滴抠出来的嘛,哈哈!
Happy Coding! :)

本文固定链接: 弘竣:Lua中的self
转载请注明: 弘竣 2020年03月22日 于 知乎 发表

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2022-4-9 11:02 | 显示全部楼层
抠性能是很好,可是你都用上Lua了,就不需要抠这么细的性能了吧
发表于 2022-4-9 11:06 | 显示全部楼层
哈哈是的,只是让大家可以多了解一些
[哈哈]
发表于 2022-4-9 11:12 | 显示全部楼层
[赞同]
发表于 2022-4-9 11:19 | 显示全部楼层
[棒]
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2025-5-8 05:03 , Processed in 0.137332 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表