Lua程序设计笔记之五: 元表

来源:互联网 发布:人工智能 国家政策 编辑:程序博客网 时间:2024/04/29 03:33

一. 元表(metatable)与元方法(metamethod):通常,Lua中的每个值都有一套预定义的的操作集合。我们可以通过元表来修改一个值的行为,使其在面对一个非预定义的操作时执行一个指定的操作。

Lua中的每个值都有一个元表,table和userdata都可以有独立的元表,而其他类型的值则共享其类型所属的单一元表。

任何table都可以作为任何值的元表,而一组相关的table也可以共享一个通用的元表,此外元表描述了他们共同的行为。一个table甚至可以作为它自己的元表,用于描述其特有的行为,总之,任何搭配形式都是合法的

__index元方法:当访问一个table中不存在的字段时,得到的结果是nil,这是对的,但是并非完全正确,实际上,这些访问会促使解释器去查找一个叫__index的元方法。如果没有这个,那么访问结果为nil,否则,就由这个元方法来提供最终结果。

在Lua中,将__index元方法用于继承是很普遍的方法,因此Lua还提供了一种更便捷的方式来实现此功能。__index元方法不必一定是一个函数,它还可以是一个table,当它是一个函数时,Lua以table和不存在的key作为参数来调用该函数。而当它是一个table时,Lua就以相同的方式来重新访问这个table。

将一个table作为__index元方法是一种快捷的,实现单一继承的方式。虽然将函数作为__index来实现相同功能的开销较大,但是函数更加灵活,可以通过函数来实现多重继承,缓存以及其他一些功能。

如果不想在访问一个table时涉及到它的__index元方法,可以使用函数rawget。调用rawget(t, i)就是对table t进行了一个"原始的(raw)"访问,不考虑元表的简单访问,但是这种原始访问并不会加速代码执行。

===================================================

二. 环境

Lua将其所有的全局变量保存再一个常规的table中,这个table称为"环境(environment)"。这种组织结构的优点在于,其一,不需要再为全局变量创造一种新的数据结构,简化了lua的内部实现。另一个优点是,可以像其他table一样操作这个table。为了便于实施这种操作,Lua将环境table自身保存再一个全局变量_G中。

===================================================

三. 面向对象编程

1. Lua中的table就是一种对象。首先,table与对象一样可以拥有状态,其次,table也与对象一样拥有一个独立其值的标识(一个self),最后,table与对象一样具有独立于创建者和创建地的生命周期。

2. 类:一个类就像一个创建对象的模具,Lua没有类的概念,每个对象只能自定义行为和形态。一些基于原型的语言,对象是没有"类型"的(objects have no classes),而是每个对象都有一个原型(prototype)。原型也是一种常规的对象,当其他对象遇到一个未知的操作时,原型会先查找它。在这种语言中要表示一个类,只需创建一个专用作其他对象的原型。类和原型都是一种组织对象间共享行为的方式。

Lua中实现原型很简单,如果有两个对象a和b,要让b作为a的一个原型:setmetatable(a, {--index = b})

3. Lua中的对象有一个特殊现象,就是无须为指定一种新行为而创建一个新类,如果只有某个对象需要某种特殊的行为,那么可以直接在该对象中实现这个行为。

4. 多重继承,实现的关键在于使用一个函数作为__index的元字段。多重继承意味着一个类可以具有多个基类,因此无法使用一个类中的方法来创建子类,而是需要定义一个特殊的函数来创建。

5. 私密性:lua在设计对象时,并没有提供私密性机制。但可以通过其他方法来实现对象的私密性,基本思路是通过两个table来表示一个对象。一个用来保存对象的状态,另一个用于对象的操作,称为"接口"。

原创粉丝点击