我是靠谱客的博主 英勇太阳,最近开发中收集的这篇文章主要介绍Lua中点和冒号的区别,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

定义:Lua中的点、冒号与self,它们之间的关系主要体现在函数的定义与调用上,Lua在函数定义时可以用点也可以用冒号,如:

复制代码
1 function mytable.fun(p)
2
return p
3 end
4
5 function mytable:fun(p)
6
return p
7 end
复制代码

用冒号定义的函数有个特别的地方是它内部有个self表示自身可以直接访问(虽然self并不是Lua的关键字,他它确实是可以访问的),如同C++、C#的this:

复制代码
1 myclass = {age = 10, name="aa"}
2
3 function myclass:fun(p)
4
print(self)
5
print(self.age)
6
print(p)
7 end
8
9 myclass:fun("22")
复制代码

输出:

table: 00D69810
10
22

可见self即myclass本身。如果上面不是冒号而是点则self不可用的会报错,因为self是个nil值。

点定义的函数可以以冒号的形式调用,冒号定义的函数也可以用点的形式来调用,两种方式都能成功调用到同一函数,但调用结果可能是错误的,上面代码最后一行的冒号改为点来调用:

myclass.fun("22")

输出:

22
nil
nil

此时self不再是自身而是传入的参数“22”,而本身需要的参数p却是nil的。可见如果冒号定义的函数用点来调用时需要传入的参数个数自动增加一个,函数内部若有用到self则self表示的便是函数传入的第一个参数,第一个参数必须传入本身,否则最后函数执行结果会是错误的。上例正确的点调用应该是:

myclass.fun(myclass, "22")

输出:

table: 00F298B0
10
22

我们反过来试一下,先来看:

复制代码
1 function myclass.fun(p1, p2)
2
print(p1)
3
print(p2)
4 end
5
6 myclass.fun("22","33")
复制代码

输出:

22
33

这个很显然,如果调用改为冒号:

myclass:fun("22","33")

输出:

table: 00E39A90
22

第一个参数p1不是“22”却是一个table,第二个参数p2才是我们传入的第一个数“22”,可见冒号调用以点定义的函数时,函数的参数的意义发生了变化,第一个参数强制变为了表示自身的变量(此时的p1等同于self),如果函数原来的参数一的意义要求不是要调用者将本身调用传入则函数执行出错,因此这种情况下的点定义的函数并不能用冒号来调用,虽然也能调用到该函数但结果却是错的。

综上:

①冒号定义成员函数相比点定义可以减少一个需要传入自身的参数,内部用self来访问自身;

②点调用冒号定义的函数时,需要多传入一个参数,传入的第二个参数开始才对应于原函数的参数列表,函数内部用到的self则变为对应于传入的第一个参数的普通变量,故传入的第一个参数应该当是调用者自身(当然如果函数内部并没有用到self则第一个参数随便传个什么都行);

③冒号调用点定义的函数时,原函数的第一个参数强制变为等同于self的变量,传入的参数从原参数的第二个参数开始才能一一对应上,因此通常这样调用都是会出错的(除非函数内部原本就把第一个参数在当self用...)。

故在Lua中成员函数的定义应该约定一种形式而不要点和冒号同时使用,不然调用者可能会不清楚该函数是否支持另一种方式的调用而增加出错的可能。


最后

以上就是英勇太阳为你收集整理的Lua中点和冒号的区别的全部内容,希望文章能够帮你解决Lua中点和冒号的区别所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部