lua中函数作为表中元素时有三种定义方式与两种调用方式

定义方式:

      ①tab.func=function ( 参数)                -- body          end

      ②function tab.func( 参数)                -- body          end

③function tab:func( 参数)                -- body          end

其中,①②两种定义方式与非表元素的函数的定义一样。方式③采用‘:’来定义,实际上隐藏了一个形参的声明,这个形参会截获调用函数时的第一个实参并把它赋值给self。

       调用方式:

      ①tab.func(参数)

      ②tab:func(参数)

其中,①调用方式与非表元素的函数的调用一样。方式②采用‘:’来调用函数,实际上隐式的把tab自己当作第一个实参传递,即tab:func(参数)相当于 tab.func(tab,参数) 。

       下面我们来看几段代码:

1. tab={}  
2. function tab.func( a,b )  
3.     print(a,b)  
4. end  
5. tab.func("第一个参数","第二个参数")

很明显,这段代码的输出为"第一个参数 第二个参数"。现在,我们保持函数定义方式不变 , 改变函数调用方式为: tab:func("a","b") 。

输出结果变为:"table: 00837338 第一个参数" ,其中table: 00837338为tab的地址。这是因为,我们改为使用':'的方式调用函数时,隐式的把tab作为第一个实参传递给了函数,即a=tab,b="第一个参数",参数("第二个参数")则被抛弃了。

1. <span >tab={}  
2. function tab:func( a,b )  
3.     print(a,b)  
4. end  
5. tab:func("第一个参数","第二个参数")  
6. </span>

这次,我们采用了第三种方式定义函数,采用第二种调用方式调用函数。输出结果为"第一个参数 第二个参数"。

现在,我们仍然保持函数定义方式不变,改变函数调用方式为:tab.func("a","b")。

输出结果变为:"第二个参数 nil"。这是因为,我们用第三种方式定义函数,则隐式地多出一个形参,假设这个形参的名字为hide。则定义函数时tab:func(a,b)就相当于tab.func(hide,a,b)。那么当我们使用'.'来调用函数时,我们只传入了两个参数,其中参数"第一个参数"传递给了hide,参数"第二个参数"传递给了a,最后,nil作为参数传递给了b。

同样的,在没改变函数调用方式之前,我们采用‘:’的方式定义和调用函数。故调用时隐式传递的参数传递给了定义时隐式定义的形参。

1. tab={str="我是字符串"}  
2. function tab:func()  
3.     print(self.str)  
4. end  
5. tab:func()

使用':'的方式定义和调用函数,函数接受到tab自己并赋值给self(self相当于c++和java中的this)。故输出为"我是字符串"。

我们也可以改变函数定义为下面的方式达到一样的效果:

1. function tab.func(myself)  
2.     print(myself.str)  
3. end