lua中 . 和 : 的区别
最近项目中使用到了 lua,因为之前没怎么接触过,特此记录下自己在学习过程中疑惑的地方。
在使用lua
进行编码的过程中,我们经常会使用到.
和:
,但是对于刚开始接触lua
的我来说,对这两者的使用还是感到时常感到疑惑,接下来我们一起看看几个例子,来感受两者的区别。如果发现文中错误的地方,请不吝赐教,谢谢!
1、基础介绍
接下来,我们看看下面的例子,来了解.
和:
的基础用法。
Car = {Name="BYD", Price=12}
print("Car 的地址 --->", Car)
print(Car.Name) -- 访问属性
-- print(Car:Name) 报错
print(string.rep("*", 20))
function Car:find1()
print(": 定义的函数并且使用 : 调用时 self 的地址--->", self)
end
function Car.find2()
print(". 定义的函数并且使用 . 调用时 self 的地址--->", self)
end
Car:find1()
Car.find2()
print(string.rep("*", 20))
function Car:find3()
print(": 定义的函数并且使用 . 调用时 self 的地址--->", self)
end
function Car.find4()
print(". 定义的函数并且使用 : 调用时 self 的地址--->", self)
end
Car.find3()
Car:find4()
运行结果:
Car 的地址 ---> table: 038F9CA0
BYD
********************
: 定义的函数并且使用 : 调用时 self 的地址---> table: 038F9CA0
. 定义的函数并且使用 . 调用时 self 的地址---> nil
********************
: 定义的函数并且使用 . 调用时 self 的地址---> nil
. 定义的函数并且使用 : 调用时 self 的地址---> nil
大家测试的时候,可以自己试一试。
Car = {Name="BYD", Price=12}
print("Car 的地址 --->", Car)
print(Car.Name) -- 访问属性
-- print(Car:Name) 报错
print(string.rep("*", 20))
function Car:find1(self)
print(": 定义的函数并且使用 : 调用时 self 的地址--->", self)
end
function Car.find2(self)
print(". 定义的函数并且使用 . 调用时 self 的地址--->", self)
end
Car:find1()
Car.find2()
print(string.rep("*", 20))
function Car:find3(self)
print(": 定义的函数并且使用 . 调用时 self 的地址--->", self)
end
function Car.find4(self)
print(". 定义的函数并且使用 : 调用时 self 的地址--->", self)
end
Car.find3()
Car:find4()
运行结果:
Car 的地址 ---> table: 039D96E0
BYD
********************
: 定义的函数并且使用 : 调用时 self 的地址---> nil
. 定义的函数并且使用 . 调用时 self 的地址---> nil
********************
: 定义的函数并且使用 . 调用时 self 的地址---> nil
. 定义的函数并且使用 : 调用时 self 的地址---> table: 039D96E0
从上面我们知道:
- 使用点号
.
来访问 table 的属性,不能使用:
来访问 table 的属性。 - 使用
.
和:
都可以用来访问 table 的函数。 - 使用
:
调用使用的.
定义的函数,默认函数传入的第一个参数是 table 本身。 - 使用
:
定义的函数并且使用:
调用时,定义的函数中默认有一个变量self
。而不是使用:
定义的函数并且使用:
调用时,定义的函数中的是没有self
变量的, 这个时候是不需要显示传入 self 参数的。
2、稍微深入的了解
通过上面的介绍,我们对 .
和:
有一个简单的了解,接下我们再稍微深入的了解下。这里先说结论,然后再看例子。
.
和:
的区别在于使用 :
- 使用
:
定义的函数时,函数隐含 self 参数,使用:
调用函数会自动传入 table 至 self 参数。而使用.
定义的函数并没有这样。 - Lua 中使用
:
可以实现面向对象方式的调用。:
只是语法糖,它同时在方法的声明与实现中增加了一个名为self
的隐藏参数,这个参数就是对象本身。
2.1 :
定义的函数的示例
classA={}
print("ClassA 地址 -->", classA)
function classA:getob(name)
print("classA:getob 中self 的地址 -->", self)
ob={}
setmetatable(ob,self)
self.__index=self
self.name=name
return ob
end
function classA:getself()
return self
end
c1=classA:getob("A")
print("c1 地址 -->", c1)
c2=classA:getob("B")
print("c2 地址 -->", c2)
print(string.rep("*",30))
print(c1:getself())
print(c2:getself())
print(string.rep("*",30))
----------------------继承------------------------
classB=classA:getob() ----非常重要,用于获取继承的self
function classB:getob(name,address)
ob=classA:getob(name)
setmetatable(ob,self)
self.__index=self
self.address=address
return ob
end
c3=classB:getob("gray.yang","shenzhen")
print("c3 地址 -->", c3)
print(c3:getself())
运行结果:
ClassA 地址 --> table: 0392D128
classA:getob 中self 的地址 --> table: 0392D128
c1 地址 --> table: 0392D010
classA:getob 中self 的地址 --> table: 0392D128
c2 地址 --> table: 0392CE80
******************************
table: 0392D010
table: 0392CE80
******************************
classA:getob 中self 的地址 --> table: 0392D128
classA:getob 中self 的地址 --> table: 0392D128
c3 地址 --> table: 03933050
table: 03933050
2.2 .
定义的函数的示例
classA={}
print(classA)
function classA.new(cls,...) --定义类方法时使用"."号,不适用隐式传参
print(cls)
this={}
setmetatable(this,cls)
cls.__index=cls --将元表的__index设为自身,访问表的属性不存在时会搜索元表
cls.init(this,...) --初始化表,注意访问类的方法都是".",此时不会隐式传入参数
return this
end
function classA.init(self,name)
print("classA.init -->", self)
self.name=name
end
function classA.getname(self)
print("classA.getname -->", self)
return self.name
end
-- 注意这里的调用方式,是 : 。
p=classA:new("gray.yang")
print("p --->", p)
print(p:getname())
print(string.rep("*",50))
运行结果:
table: 0381B888
table: 0381B888
classA.init --> table: 0381B8D8
p ---> table: 0381B8D8
classA.getname --> table: 0381B8D8
gray.yang
**************************************************
熟悉其他面向语言的同学,看了上面的例子,应该对.
和:
有了了解,接下来自己平常多写写就明白了。
参考资料