美文网首页
LUA学习笔记 -- 类

LUA学习笔记 -- 类

作者: 奥利奥蘸墨水 | 来源:发表于2020-06-21 23:52 被阅读0次

引述

LUA中的表就是一个对象:

  • 表与对象一样可以拥有状态
  • 表与对象一样都拥有一个与值无关的标识:self
  • 两个具有相同值的对象(表)是两个不同的对象,而一个对象可以拥有多个不同的值
  • 表与对象一样,拥有与创建着和被创建位置无关的生命周期

对象有自己的操作,表也有,例:

People = {money = 0}

function People.earn_money(money)
    People.money = People.money + money
end

上面的代码创建了一个新函数,并将该函数存入People的earn_money字段,然后就可以进行如下调用:

People.earn_money(100)

接下来换一种方法表示这个函数:

function People.earn_money(self, money)
    self.money = self.money + money
end

上述方法通过对操作的接受者进行操作,替代了原来的直接调用全局名称People

通过使用参数self,可以对多个对象调用相同的方法:

People = {money = 0}

function People.earn_money(self, money)
    self.money = self.money + money
end

p1 = {money = 0, earn_money = People.earn_money}
p2 = {money = 0, earn_money = People.earn_money}

p1.earn_money(p1, 100)
p2.earn_money(p2, 200)

print(p1.money) -- 100
print(p2.money) -- 200

LUA中有一种语法糖,使用冒号操作符隐藏传入的self参数,我们可以将上述函数重写为:

function People:earn_money(money)
    self.money = self.money + money
end

可以使用冒号来定义函数,同样也可以使用冒号来调用方法,所以可以将上述例子重写为:

People = {money = 0}

function People:earn_money(money)
    self.money = self.money + money
end

p1 = {money = 0, earn_money = People.earn_money}
p2 = {money = 0, earn_money = People.earn_money}

p1:earn_money(100)
p2:earn_money(200)

print(p1.money) -- 100
print(p2.money) -- 200

类(Class)

LUA语言中本没有类的概念,虽然元表的概念在某种程度上与类的概念相似,但是把原表当作类使用在后续会比较麻烦。相反,我们可以参考基于原型的语言中的一些做法来在LUA语言中模拟类。在这些语言中,对象不属于类,每个对象可以有一个原型。原型也是一种普通的对象,当对象遇到遇到一个未知操作时,会首先在原型中查找。要在这种语言中表示一个类,我们只需要创建一个专门被用作其他对象(类的实例)的原型对象即可。类和原型都是一种组织多个对象间共享行为的方式。

在LUA语言中,如果有两个对象A和B,要让B成为A的一个原型,只需要:

setmetatable(A, {__index = B})

使用上述的People的例子,我们可以使用__index方法让这些新对象从People中继承earn_money操作:

People = {money = 0}

function People:earn_money(money)
    self.money = self.money + money
end

function People.new(o)
    o = o or {}
    setmetatable(o, {__index = People})
    return o
end

p1 = People.new{money = 0} -- 创建p1对象

p1:earn_money(100) -- getmetatable(p1).__index.earn_money(p1, 100)

print(p1.money) -- 100

在上述例子中,我们让p1的元表设置为{__index = People},这样当p1对象中找不到earn_money方法时,就会去元表中的__index中搜索,此时实际上发生了如下调用:

getmetatable(p1).__index.earn_money(p1, 100)

再使用LUA提供的语法糖(冒号方法),可以将上述new函数写成如下:

function People:new(o)
    o = o or {}
    self.__index = self
    setmetatable(o, self)
    return o
end

继续上面的例子,p1调用earn_money方法的时候会按照如下格式调用:

p1:earn_money(100)

实质上调用方式是:

p1.earn_money(p1, 100)

那么就是执行了:

p1.money = p1.money + 100

等号后面p1.money是继承父类的0,赋值完成之后,p1就拥有了money这个属性,并且值为100,此后再调用此属性的时候就不会再涉及元方法了。

相关文章

  • LUA学习笔记 -- 类

    引述 LUA中的表就是一个对象: 表与对象一样可以拥有状态 表与对象一样都拥有一个与值无关的标识:self 两个具...

  • 2021-08-06_lua脚本学习笔记

    20210806_lua脚本学习笔记 1概述 1.1为什么lua脚本具有原子性 Redis保证以原子方式执行脚本,...

  • 2022-05-02_Lua脚本操作redis锁学习笔记

    20220502_Lua脚本操作redis锁学习笔记.md 1概述 释放锁要用 lua 脚本,把检查锁是不是本线程...

  • 2019-01-14

    Lua与C交互学习笔记 Lua与C交互是通过虚拟栈实现的 在C中调用Lua 方法一 栈中的情况如下表所示 方法二 ...

  • Lua学习笔记

    函数调用: lua函数在两种情况下,可以省略’()’:函数中参数是一个单独的字符串或者表。因此,myfunc{a=...

  • Lua 学习笔记

    1. dummy variables(虚变量) Usually,I reserve the identifier ...

  • Lua学习笔记

    1.元表中的算术操作符对应字段 __add:加法__sub:减法__union:整合去重__dev:除法__unm...

  • Lua学习笔记

    参考Lua 5.3 参考手册Lua 5.1 参考手册云风的blogLua开发者论坛Pogramming in Lu...

  • lua学习笔记

    最近项目要用的lua 所以抽空学习 记录一下 IDE有ZeroBrane Studio 我还是用的sublime...

  • Lua 学习笔记

    最近要用到 Lua 编程语言,所以学习了一些简明教程,同时记录一下 Lua 编程语言相对于其他主流编程语言在语法上...

网友评论

      本文标题:LUA学习笔记 -- 类

      本文链接:https://www.haomeiwen.com/subject/eyeaxktx.html