笔者不知不觉开始用cocos2dx-lua写项目有2个月左右了,闲来无事,且来谈论一番lua的特殊之处。
一:函数调用方式。在java,javaScript,C++(指针除外)中通过“对象”调用方法通常都是用.(点);然而在lua中调用“对象”(此处勿纠结lua的“伪对象--元表”)通常是用:(冒号)。但若是非要用.(点)调用lua“对象”的方法也是可以的,在笔者看来区别有两点,1:用冒号调用的函数,会自带一个“隐形默认参数”---self,也就是在函数内部,可以直接通过self.的方式访问lua“对象”的属性;而用.调用函数的话,若不事先把self作为参数传递进来,函数内部则无法直接使用self关键字来访问对象属性。2:调用父类的构造函数使用:(冒号)调用时,父类构造函数里的self的值将不是你所期望的self的值,这非常特殊,因此调用构造函数最好用self.super.ctor(self)的方式。
二:一些语法小细节区别。1:在lua中无法使用譬如i+=1,i*=1等“精简”运算符,而必须i=i+1,i=i*1。2:在lua中无法在一个程序块非“末尾”位置使用return,比如(下面多数代码片段是笔者随意截图了项目的一部分,读者不必试图运行)
local score = data.dlContribution or "777"
return
local diamond = data.diamond or "23333"
这时候会编译报错出现红线的,在end之前,即“末尾”使用return则不会报错。
function Refresh()
local i = 0
return
end
在elseif之前也是可以的。
function ClubDetail:refreshCurrPage()
if self._currPage:getTag() == TAG_MENBER then
self:onMemberRefresh(1, 20)
elseif self._currPage:getTag() == TAG_SCOREHIS then
self:onHistoryRefresh()
return
elseif self._currPage:getTag() == TAG_MGR then
self._currPage:initData(self.data)
end
end
那么如果非要在中途return要怎么做呢?可以这样:
local score = data.dlContribution or "777"
do return end
local diamond = data.diamond or "23333"
三:lua认为只有nil和false才是逻辑false,其他都为逻辑true。这和C/C++不同,C/C++认为0是false。因此这种写法也是会进if的内容的。
if 0 then
print("在lua里0也是逻辑true哦")
end
四:函数多返回值。这一点很特殊,须知java,javaScript,C++等等笔者熟悉的语言都是单返回值。lua可以用以下的方式来接受函数的多返回值:
local getNumber = function()
return 1 , 2
end
local i, j = getNumber()
此时i和j分别为1,2。若getNumber只返回1个值,则j为nil;若没有j,则return出来的2被抛弃,i=1。此函数只返回了2 个值,也可以返回3个4个,然后用相应个数变量去接收,以此类推。
五:循环。在java,javaScript,C++中,for循环是有3个条件,且用;隔开的。在lua中使用,(逗号)而且“显式”的条件可以只有2个如:
for i = 1, 4 do
print("i is ",i)
end
循环执行4次,从1执行到4。此处忽略了递增值(默认递增1),当然了,也可以写出被隐藏的默认递增值:
for i = 1, 4, 1 do
print("i is ",i)
end
六:方法和成员重名的将导致调用方法时出现歧义。如:
-- 设置地图是否升级了
function xx:setMapLevelUp(isMapLevelUp)
self.isMapLevelUp = isMapLevelUp
end
-- 获取地图是否升级了
function xx:isMapLevelUp()
return self.isMapLevelUp
end
isMapLevelUp方法和isMapLevelUp成员重名,则调用时会出现歧义,lua认为xx:isMapLevelUp()是访问了一个bool值,而非方法调用