事先声明,本文主要用于个人笔记,不保证原创性
开始
理论
冒号的作用:
1、定义函数时,给函数添加隐藏的第一个参数 self
2、调用函数时,默认把当前调用者作为第一个参数传递进去
如 a:b© 可以理解为 a.b(a, c)
第一个例子
以下是用点号的定义和调用函数的方式:
Song =
{
name = "",
timeLength = 0,
}
function Song.SetName(name)
Song.name = name;
end
假设有如下代码,则会发生报错
第二个例子
Song = {
name = "",
timeLength = 0,
}
function Song.SetName(name)
Song.name = name
-- 因为Name字段属于Song的内容,因此这里需要用到Song的前缀
--这样会有一个缺陷,Song变成一个全局变量,就算拷贝多个Song,它们也会共用一个name
--同时Song本身不能被销毁
end
local ChineseSong = Song
--将Song复制一份,存入ChineseSong,两者不属于同一个对象
Song= nil
--此时由于Song被回收,即Song.name被回收
ChineseSong.SetName("逆光")
--因为Song.name被回收,因此SetName操作会给一个nil赋值,自然就<font color=#ff0000>报错</font>了
print(ChineseSong.name)
为了避免Song.name共用,因此要让每个对象使用自己的name字段,实现过程如下所示:
第三个例子
Song = {
name = "",
timeLength = 0,
}
function Song.SetName(copyObj,name)
copyObj.name = name
end
local ChineseSong = Song
Song= nil
ChineseSong.SetName(ChineseSong,"逆光")
print(ChineseSong.name)
这里用copyObj替代原本的Song对象,然后每次调用的时候将copy的对象传进来,就可以让每个对象访问自己的name了,但这么做很麻烦,lua为了简化操作,做了一个语法糖(可以理解为小窍门),即对于使用冒号访问时,自动把调用者本身传过去,于是对生面的代码进行简化
第四个例子
Song = {
name = "",
timeLength = 0,
}
function Song.SetName(copyObj,name)
copyObj.name = name
end
local ChineseSong = Song
Song= nil
ChineseSong:SetName("逆光")
--用了冒号语法糖以后,调用方法时会默认将调用者本身传入,即常说的self
print(ChineseSong.name)
该段代码能与例子3打到同样的效果,但少写了一遍ChineseSong,变相的减少了工作量(非重点,更多的是为了代码可读性)。到这里看起来很完美了,对吧?我们已经通过自己的努力, 每次少写了一遍CineseSong,但别忘了,在SetName方法处,还有一个copyObj显得很扎眼,我们可不可以通过某种方式在不出错的情况下将其删掉?
显然是可以的,方法还是使用今天的主角,即冒号,请看如下代码:
第五个例子
Song = {
name = "",
timeLength = 0,
}
-- 使用冒号声明方法,lua内部接受传入的第一个参数,并将其存入self
-- 这种写法等效于
-- function Song.SetName(copyObj,name)
-- self = copyObj
-- self.name = name
-- end
function Song:SetName(name)
self.name = name
end
local ChineseSong = Song
Song= nil
ChineseSong:SetName("逆光")
print(ChineseSong.name)
至此,看起来是不是顺眼多了?
参考文档:
1、lua — 点号 和 冒号
4119

被折叠的 条评论
为什么被折叠?



