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

首先,先来一段在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

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

时间: 2024-07-30 17:58:49

[转]lua面向对象编程之点号与冒号的差异详细比较的相关文章

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

首先,先来一段在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()

OOP面向对象编程之java打飞机游戏

#写在前面 继上一篇OOP面向对象编程之俄罗斯方块项目实现过程,OOP面向对象编程之java打飞机游戏,其实写的很简单,也很容易理解,并且注释写的很清楚了,还有问题,自己私下去补课学习(顺便做50个深蹲,嘿嘿,平时干嘛去了),看图:   #完整代码   敌飞机 package com.tarena.fly; import java.util.Random; /** * 敌飞机: 是飞行物,也是敌人 */ public class Airplane extends FlyingObject imp

深入理解JavaScript系列(17):面向对象编程之概论

介绍 在本篇文章,我们考虑在ECMAScript中的面向对象编程的各个方面(虽然以前在许多文章中已经讨论过这个话题).我们将更多地从理论方面看这些问题. 特别是,我们会考虑对象的创建算法,对象(包括基本关系 - 继承)之间的关系是如何,也可以在讨论中使用(我希望将消除之前对于JavaScript中OOP的一些概念歧义). 英文原文:http://dmitrysoshnikov.com/ecmascript/chapter-7-1-oop-general-theory/ 概论.范式与思想 在进行E

LUA脚本中的方法使用冒号和点,以及调用者使用冒号和点

1.Lua脚本里方法之前的冒号和点: 备注:每个方法前面如果是冒号,则这个方法里面自带一个self属性,也就是这个LUA脚本自己类对象的self,当为点时,自带的self属性则为nil 调用者:local zwt = require "ZWTestLuaScript1" 被调者:ZWTestLuaScript1脚本中的方法如下: 方法1: function ZWTestLuaScript1:OnSumbitBtnLogin(x,y) print(self) print(x) print

Lua中调用函数使用点号和冒号的区别

最简单的类 TSprite = { x = 0, y = 0, } function TSprite.setPosition(x, y) TSprite.x = x; TSprite.y = y; end TSprite.setPosition(1, 2); print("TSprite坐标(" .. TSprite.x .. "," .. TSprite.y .. ")"); mSprite.setPosition TSprite = { x

LUA中点号和冒号的区别

Student = {}; Student.__index = Student; function Student:new(name, age) local temp = {}; setmetatable(temp, Student); temp.name = name; temp.age = age; return temp; end function Student:info() print(self.name, self.age); --运行stu2时会报错 -- print("name:

面向对象编程之OC

面向对象概述 面向对象是一种符合人类思想习惯的编程思想.现实生活中存在各种形态不同的事物,这些事物之间存在着各种各样的联系,在程序中使用对象来映射现实中的事物,使用对象的关系来描述事物之间的联系,这种思想就是面向对象. 提到面向对象,自然会想到面向过程.面向过程就是分析解决问题所需的步骤,然后用函数把这些步骤一一实现,使用的时候一个一个一次调用就可以了. 面向对象则是把解决的问题按照一定的规则划分为多个独立的对象,然后通过调用对象的方法来解决问题.当然,一个应用程序会包含多个对象,通过多个对象的

c++中的点号(.),冒号(:)和双冒号(::)运算符

1.冒号(:)用法 (1)表示机构内位域的定义(即该变量占几个bit空间) typedef struct _XXX{ unsigned char a:4;  //char型的字符a占4位 unsigned char c; } XXX; (2)构造函数后面的冒号起分割作用,是类给成员变量赋值的方法,初始化列表,更适用于成员变量的常量const型. struct _XXX{ _XXX() : y(0xc0) { } }; (3) public:和private:后面的冒号,表示后面定义的所有成员都是

lua编程之lua与C相互调用

lua是扩展性非常良好的语言,虽然核心非常精简,但是用户可以依靠lua库来实现大部分工作.除此之外,lua还可以通过与C函数相互调用来扩展程序功能.在C中嵌入lua脚本既可以让用户在不重新编译代码的情况下修改lua代码更新程序,也可以给用户提供一个自由定制的接口,这种方法遵循了机制与策略分离的原则.在lua中调用C函数可以提高程序的运行效率.lua与C的相互调用在工程中相当实用,本文就来讲解lua与C相互调用的方法. Lua与C相互调用的首要问题是如何交换数据,lua API使用了一个抽象的栈与