打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
lua面向对象编程之点号与冒号的差异详细比较

lua面向对象编程之点号与冒号的差异详细比较

2011-07-28 02:02 by youxiachai, 4715 阅读, 4 评论, 收藏, 编辑

首先,先来一段在lua创建一个类与对象的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Class = {}
Class.__index = Class
function Class:new(x,y)
    local temp = {}
    setmetatable(temp, Class)
    temp.x = x
    temp.y = y
    return temp
end
function Class:test()
    print(self.x,self.y)
end
object = Class.new(10,20)
object:test()

猜一下会输出什么结果呢?

输出:

>lua -e "io.stdout:setvbuf 'no'" "object.lua"
20    nil
>Exit code: 0

我们的y值怎么没了?

这个原因很简单,因为我们创建一个对象的时候使用了一个 . 号

在lua程序设计第二版中,有提到当一项操作所作用的”接受者”,需要一个额外的参数来表示该接受者,这个参数通常称为self或this

然后我们在这段代码加上 self

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Class = {}
Class.__index = Class
function Class:new(x,y)
    local temp = {}
    setmetatable(temp, Class)
    temp.x = x
    temp.y = y
    return temp
end
function Class:test()
    print(self.x,self.y)
end
object = Class.new(self,10,20)
object:test()

然后我们在看一下输出

>lua -e "io.stdout:setvbuf 'no'" "object.lua"
10    20
>Exit code: 0

这下就正常了!!嗯,每次创建一个对象的时候都有写一个self,会不会感觉很麻烦呢?lua提供了用冒号的方式在一个方法定义中添加一个额外的参数,以及在一个方法调用中添加一个额外的实参

然后代码改成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Class = {}
Class.__index = Class
function Class:new(x,y)
    local temp = {}
    setmetatable(temp, Class)
    temp.x = x
    temp.y = y
    return temp
end
function Class:test()
    print(self.x,self.y)
end
object = Class:new(10,20)
object:test()

输出正常:

>lua -e "io.stdout:setvbuf 'no'" "object.lua"
10    20
>Exit code: 0

如果,就这么完的话,本来是一件很欢乐的事情,但是,我尝试了一下以下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Class = {}
Class.__index = Class
function Class.new(x,y)
    local temp = {}
    setmetatable(temp, Class)
    temp.x = x
    temp.y = y
    return temp
end
function Class:test()
    print(self.x,self.y)
end
object = Class.new(10,20)
object:test()

出乎意料的是:

>lua -e "io.stdout:setvbuf 'no'" "object.lua"
10    20
>Exit code: 0

代码正常运行….这个让人很费解,本来,点号对方法的操作是需要一个额外的接受者,第一段代码已经说明了这个问题,但是,现在程序有正常运行,令我真是有点费解…

然后,我接着尝试又发现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Class = {}
Class.__index = Class
function Class.new(x,y)
    local temp = {}
    setmetatable(temp, Class)
    temp.x = x
    temp.y = y
    return temp
end
function Class:test()
    print(self.x,self.y)
end
object = Class:new(10,20)
object:test()

输出结果:

>lua -e "io.stdout:setvbuf 'no'" "object.lua"
table: 003CACA0    10
>Exit code: 0

这个只不过跟第一段代码点号和冒号的位置调换了一下,就出现了这样的结果…

如果,你仔细想想,这里和第一段代码的区别,可以发现,其实,这里就可以证明了冒号其实就是默认传了一个实参到方法中

为了证明冒号的作用,我改动了一下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Class = {}
Class.__index = Class
function Class:new(x,y)
    local temp = {}
    setmetatable(temp, Class)
    temp.x = x
    temp.y = y
    return temp
end
function Class.test()
    print(self.x,self.y)
end
object = Class:new(10,20)
object:test()

输出的结果是:

>lua -e "io.stdout:setvbuf 'no'" "object.lua"
lua: object.lua:15: attempt to index global 'self' (a nil value)
stack traceback:
    object.lua:15: in function 'test'
    object.lua:21: in main chunk
    [C]: ?
>Exit code: 1

从这里的错误可以看出,没有self这个参数,竟然,方法用的是点号,那我们试一下把对象传进去看下能不能正常运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Class = {}
Class.__index = Class
function Class:new(x,y)
    local temp = {}
    setmetatable(temp, Class)
    temp.x = x
    temp.y = y
    return temp
end
function Class.test()
    print(self.x,self.y)
end
object = Class:new(10,20)
object:test(object)

遗憾的是这样的改动是错误的,错误的结果也是一样的

>lua -e "io.stdout:setvbuf 'no'" "object.lua"
lua: object.lua:15: attempt to index global 'self' (a nil value)
stack traceback:
    object.lua:15: in function 'test'
    object.lua:21: in main chunk
    [C]: ?
>Exit code: 1

那我们这次尝试下想刚才那样,把方法的点号搞成一致看下效果怎样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Class = {}
Class.__index = Class
function Class:new(x,y)
    local temp = {}
    setmetatable(temp, Class)
    temp.x = x
    temp.y = y
    return temp
end
function Class.test()
    print(self.x,self.y)
end
object = Class:new(10,20)
object.test()

遗憾的是跟之前不一样,还是不能运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Class = {}
Class.__index = Class
function Class:new(x,y)
    local temp = {}
    setmetatable(temp, Class)
    temp.x = x
    temp.y = y
    return temp
end
function Class.test()
    print(self.x,self.y)
end
object = Class:new(10,20)
object.test()
1
  
1
回想一下,冒号的作用可以传递一个实参,对于方法的操作我们需要一个接受者,那么进行以下的改动
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Class = {}
Class.__index = Class
function Class:new(x,y)
    local temp = {}
    setmetatable(temp, Class)
    temp.x = x
    temp.y = y
    return temp
end
function Class:test()
    print(self.x,self.y)
end
object = Class:new(10,20)
object.test(object)

这次输出就正常了

>lua -e "io.stdout:setvbuf 'no'" "object.lua"
10    20
>Exit code: 0

这段代码告诉了我们,想要操作一个方法就一定需要一个额外参数来表示该值,对于点号,我们必须显示传递一个实参,才能使程序正常运行,而为了方便,我们可以直接使用冒号来简化操作.

结论:

罗嗦了半天其实,可以用一下一句话来避免这个问题:

用lua进行面向对象的编程,声明方法和调用方法统一用冒号,对于属性的调用全部用点号

 

搞这么多其实,只是加深理解罢了…欢迎交流和批评..


作者:游戏阿柴
出处:http://www.cnblogs.com/youxilua
本文采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
微博联系:新浪微博
用支付宝赞助博主:http://me.alipay.com/youxilua

  • Categories: lua
Add your comment
  1. #1楼 brucexu   2012-05-20 21:31
    不错,帮我也弄清楚了点号和冒号的区别
    应该点号是正统的格式,冒号只是对它的封装
  2. #2楼 yhh行者   2013-07-13 13:51
    谢谢博主,对象我这样的新手很有用!3Q
  3. #3楼[楼主] youxiachai   2013-07-14 09:40
    @yhh行者
    !!!!!!!!!!!!!!!!!!!吓到我了...
  4. #4楼 约翰?码农   2013-10-17 16:53
    第一个代码为什么y值会丢了,博主没解释清楚哦
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
lua中的面向对象模拟,类,继承,多态
Lua学习之function
Metatable In Lua 浅尝辄止(转)
Python新手学习面向对象编程基础,创建类和实例化详细讲解
Objective
Quick
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服