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