Lua中调用函数使用点号(.)和冒号(:)的区别

2015年06月30日

lua函数的调用有两种形式

示例:

mSprite.setPosition(100, 20);

mSprite:setPosition(100, 20);

最简单的类

我们先来看看简单的,来创建一个“类”试试,如下代码:

    MSprite = {
        x = 0,
        y = 0,
    }
    function MSprite.setPosition(x, y)
        Msprite.x = x;
        Msprite.y = y;
    end
   
    MSprite.setPosition(1, 2);
    print("MSprite坐标(" .. MSprite.x .. "," .. MSprite.y .. ")");

本质是创建了一个table,并给table添加一些属性。 输出结果如下:

MSprite坐标(1,2)

setPosition函数,函数本质是通过MSprite这个table来调用x和y字段的。 并且,通过setPosition的方式是,使用点号(.),此乃常规的函数调用方式。

##不用table的本名可以吗?——self的作用 上面的例子,如果这样调用的话:

    local who = MSprite;
    MSprite = nil;
   
    who.setPosition(1, 2);

运行会报错,虽然通过who确实可以成功调用setPosition函数,但函数里需要用到MSprite,而此时的MSprite已经为nil了。

然而可以这么做:

    Msprite = {
        x = 0,
        y = 0,
    }
    function Msprite.setPosition(self, x, y)
        self.x = x;
        self.y = y;
    end
   
    local who = Msprite;
    Msprite = nil;
     
    who.setPosition(who, 1, 2);
    print("Msprite坐标(" .. who.x .. "," .. who.y .. ")");

输出结果仍然是:

Msprite坐标(1,2)

注意到setPosition的第一个参数,我们强制要求传入一个参数,这个参数就是Msprite本身。于是,在调用setPosition函数时,传入who,who的内容就是Msprite的内容,于是,setPosition就能正常执行了。

##方便的偷懒方法——默认的self参数,以及默认传递self参数

如果每次创建函数和调用函数都要这么去处理self,那他一定不是程序员 所以,Lua提供了一个新的使用方式–冒号(:)。

如下代码:

    Msprite = {
        x = 0,
        y = 0,
    }
    function Msprite:setPosition(x, y)
        self.x = x;
        self.y = y;
    end
    local who = Msprite;
    Msprite = nil;
     
    who:setPosition(1, 2);

第一,留意setPosition函数的定义,使用了冒号;

第二,留意setPosition函数的调用,使用了冒号。

冒号的作用就是:

定义函数时,给函数的添加隐藏的第一个参数self;

调用函数时,默认把当前调用者作为第一个参数传递进去。

使用了冒号之后,就相当于我们刚刚使用点号时一样,只是我们不再需要显式地定义self参数以及主动地传递who参数。

##最后 点号和冒号的区别,由此明了:冒号是为了方便(为偷懒而生)。

如果是使用Cocos2d-x lua来开发的话,大部分情况下都是使用冒号的。

原因很简单,因为大部分情况下我们都要使用到self参数,就像C++的this关键字一样。