元表(metatable)

元表为重定义Lua中任意一个对象(值)的默认行为提供了一种公开入口. 如同许多OO语言的操作符重载或方法重载.

算术类元方法:     字段:__add  __mul  __ sub  __div  __unm  __mod  __pow  (__concat)

代码:(两个table相加)

下例中mt是元表,__add是元方法

tA = {1, 3}
tB = {5, 7}

--tSum = tA + tB
mt = {}

mt.__add = function(t1, t2)
    for _, item in ipairs(t2) do  --这里的_可以改成任意字符
        table.insert(t1, item)
    end
return t1
end

setmetatable(tA, mt) --定义table tA的重载运算符_add  setmetatable(只能用于table)

tSum = tA + tB

for k, v in pairs(tSum) do
    print(v)
end

输出:

1
3
5
7

关系类元方法: 字段:__eq __lt(<) __le(<=),

--比较集合大小 <
mt = {}
function mt.__lt(tA, tB)
    return #tA < #tB
end

tA, tB = {3}, {1, 2}

setmetatable(tA, mt)
setmetatable(tB, mt)

print(tA < tB)

#是表的长度运算符

比如

local a = {4,5,6,7,8}

print(#a)

会输出5

相当于table.getn(a)

在Lua本身提供的功能中, 不允许你改变除了table类型值外的任何其他类型值的Metatable, 除非使用C扩展或其他库. setmetatable和getmetatable是唯一一组操作table类型的Metatable的方法.

关于__index:

__index元方法:
按照之前的说法,如果A的元表是B,那么如果访问了一个A中不存在的成员,
就会访问查找B中有没有这个成员。这个过程大体是这样,但却不完全是这样,实际上,即使将A的元表设置为B,而且B中也确实有这个成员,返回结果仍然会是
nil,原因就是B的__index元方法没有赋值。按照我的理解,__index方法是用来确定一个表在被作为元表时的查找方法

    father = {
        house=1
    }
    son = {
        car=1
    }
    setmetatable(son, father) --把son的metatable设置为father
    print(son.house)

输出的结果是nil,但如果把代码改为

    father = {
        house=1
    }
    father.__index = father -- 把father的__index方法指向自己
    son = {
        car=1
    }
    setmetatable(son, father)
    print(son.house)

输出的结果为1,符合预期

在上述例子中,访问son.house时,son中没有house这个成员,但Lua接着发 现son有元表father,于是此时father被当做元表来查找,此时,Lua并不是直接在father中找名为house的成员,而是调用 father的__index方法,如果__index方法为nil,则返回nil,如果是一个表(上例中father的__index方法等于自己,就 是这种情况),那么就到__index方法所指的这个表中查找名为house的成员,于是,最终找到了house成员。
注:__index方法除了可以是一个表,还可以是一个函数,如果是一个函数,__index方法被调用时将返回该函数的返回值。

时间: 2024-08-25 18:31:00

元表(metatable)的相关文章

lua元表(metatable)和元方法(metamethod)

元表概念: 引言:Lua中的每个值都有一套预定义的操作集合,如数字相加等.但无法将两个table相加,此时可通过元表修改一个值的行为,使其在面对一个非预定义的操作时执行一个指定操作. 访问机制:一般的元方法都只针对Lua的核心,也就是一个虚拟机.它会检测一个操作中的值是否有元表,这些元表是否定义了关于次操作的元方法.例如两个table相加,先检查两者之一是否有元表,之后检查是否有一个叫“__add”的字段,若找到,则调用对应的值.“__add”等即时字段,其对应的值(往往是一个函数或是table

lua面向对象封装及元表(metatable)性能测试

Lua本身是没有面向对象支持的,但面向对象编程在逻辑复杂的大型工程却很有用.于是很多人用Lua本身的数据结构table来模拟面向对象.最简单的一种方法是把对象的方法.成员都放到table中.如: -- file:test.lua local test = {} function test:get_x() return self.x or 0 end function test:set_x( _x ) self.x = _x end local test_module = {} function

Lua&#30340;&#20803;&#34920;(metatable)

metatable允许我们改变table的行为 Lua中的每一个表都可以有metatable(后面我们将看到userdata也有Metatable) Lua默认创建一个不带metatable的新表 setmetatable(只能用于table)和 getmetatable(用于任何对象) 可以使用setmetatable函数设置或者改变一个表的metatable 任何一个表都可以是其他一个表的metatable 一组相关的表可以共享一个metatable(描述他们共同的行为) 一个表也可以是自身

Lua——3.元表Metatable

lua的metatable也是一个普通的表,lua提供metatable的功能,主要有一下几种作用: 控制对 table 的访问 为 Lua 函数库提供支持 重载算数运算符和关系运算符的行为 1.使用metatable控制对table的访问 当查询table的某个键的时候,如果该table的这个键没有值,那么Lua就会寻找该table的metatable中的__index元方法:如果__index指向一个table,Lua会在此table中查找相应的键, 并且,__index也可以指向一个方法

lua元表Metatable

Lua 中的每个值都可以用一个 metatable. 这个 metatable 就是一个原始的 Lua table , 它用来定义原始值在特定操作下的行为. 你可以通过在 metatable 中的特定域设一些值来改变拥有这个 metatable 的值 的指定操作之行为. 举例来说,当一个非数字的值作加法操作的时候, Lua 会检查它的 metatable 中 "__add" 域中的是否有一个函数. 如果有这么一个函数的话,Lua 调用这个函数来执行一次加法. 我们叫 metatable

Lua中的元表(metatable)、元方法(metamethod)详解

在第一次看见这两样东西的时候,可能会觉得它很深奥,但其实很好理解,虽然实际上它可能真的很深奥.(小若:停!滚粗.) 1.知道为什么1 + 1 = 2吗? 为什么在Lua中,1+1会等于2呢?(小若:难道除了Lua,其他地方就不等于2了?)为什么数字和数字相加是合法的,为什么table和table相加就会报错?大家有想过这些问题吗? 没错,规则,这一切都只是规则而已,Lua规定了数字之间可以进行加减乘除,而table之间则不可以. 这是因为,在人类世界里,并没有table和table相加的概念. 

Lua学习笔记-metatable元表

本以为看完C API lua就学的差不多了,没想到越陷越深啊. 首先说元表的概念,元表是一个特殊的表,作用是定义一个表的操作.类似于C++中类的运算符重载. 使用元表需要注意的事项: 1.元表可以定义的操作有下面这些 1 __add(a, b) --加法 2 __sub(a, b) --减法 3 __mul(a, b) --乘法 4 __div(a, b) --除法 5 __mod(a, b) --取模 6 __pow(a, b) --乘幂 7 __unm(a) --相反数 8 __concat

lua学习笔记16:table元表详解

一 table本质 Lua中table本质实际上是个类似HashMap东西. 其元素是很多的Key-Value对,类似iOS中的字典NSDictionary. 如果尝试访问了一个表中并不存在的元素时,就会触发Lua的一套查找机制. lua"面向对象"就是凭借这个机制实现的. 示例: local tab = {} print(tab.key) 输出:nil 因为tab中没有任何元素,当然视图访问其key元素时就会找不到,所以返回nil. 二 元表metatable 元表,即元素列表,是t

lua——元表、元方法、继承

[元表] 元表中的键为事件(event),称值为元方法(metamethod). 通过函数getmetatable查询任何值的元表,通过函数setmetatable替换表的元表. setmetatable(只能用于table)和getmetatable(用于任何对象) 语法:setmetatable (table, metatable),对指定table设置metatable      [如果元表(metatable)中存在__metatable键值,setmetatable会失败] 语法:tm