Lua元表

Lua元表

概念:

  • 任何变量都可以作为另一个表变量的元表
  • 任何表变量都可以有自己的元表
  • 当我们子表中进行一些特定操作时,会执行元表中的内容

一、设置元表

使用setmetatable(table,metaTable)

meta = {}
myTable = {}
--设置元表函数
--第一个参数 子表
--第二个参数 元表
setmetatable(myTable,meat)

二、特定操作__tostring

当子表要被当做字符串使用时, 会默认调用这个元表中的__tostring方法
示例代码:

meat = {
    --当子表要被当做字符串使用时, 会默认调用这个元表中的__tostring方法
    __tostring = function (t)
        return t.name
    end
}
myTable = {
    name = "Lua"
}
setmetatable(myTable,meta)
print(myTable)

输出结果:

Lua

三、特定操作__call

当子表被当作一个函数来使用时, 会默认调用这个__call中的内容

meta = {
	__call = function()
		print("call方法")
	end
}
myTable = {
	name = "Lua"
}
setmetatable(myTable,meta)
myTable()

输出结果:

call方法

作为函数使用时,也可以往里面传入参数,但第一个参数默认是调用自己

meta = {
	__tostring = function(t)
		return t.name
	end,
	__call = function(a,b)
		print(a)
		print(b)
		print("call方法")
	end
}
myTable = {
	name = "Lua"
}
setmetatable(myTable,meta)
myTable(1)

输出结果:

Lua
1
call方法

四、运算符重载

名称关键字
加法__add
减法__sub
乘法__mul
除法__div
取模__mod
幂运算__pow
等于__eq
小于__lt
小于等于__le

示例:

meta4 = {
    --相当于运算符重载 当子表使用+ 会调用该方法
    -- +
    __add = function (t1,t2)
        return t1.age + t2.age
    end,
    -- -
    __sub = function (t1,t2)
        return t1.age - t2.age        
    end,
    -- *
    __mul = function (t1,t2)
        return t1.age * t2.age
    end,
    -- /
    __div = function (t1,t2)
        return t1.age / t2.age
    end,
    -- %
    __mod = function (t1,t2)
        return t1.age % t2.age
    end,
    -- 幂运算
    __pow = function (t1,t2)
        return t1.age ^ t2.age
    end,
    -- ==
    __eq = function (t1,t2)
        return t1.age == t2.age
    end,
    -- <
    __lt = function (t1,t2)
        return t1.age < t2.age
    end,
    -- <=
    __le = function (t1,t2)
        return t1.age <= t2.age
    end,
    -- ..
    __concat = function (t1,t2)
        return t1.age .. t2.age
    end

}
myTable4 = {age = 1}
setmetatable(myTable4,meta4)
myTable5 = {age = 2}
setmetatable(myTable5,meta4)

--myTable5不设置元表也能运行
print("+ :  "..tostring(myTable4 + myTable5))
print("- :  "..tostring(myTable4 - myTable5))
print("* :  "..tostring(myTable4 * myTable5))
print("/ :  "..tostring(myTable4 / myTable5))
print("% :  "..tostring(myTable4 % myTable5))
print("^ :  "..tostring(myTable4 ^ myTable5))

--如果要用条件运算符来比较连个对象
--这两个对象的元表一定要一致, 才能准确调用方法
print("== :  "..tostring(myTable4 == myTable5))
print("< :  "..tostring(myTable4 < myTable5))
print("<= :  "..tostring(myTable4 <= myTable5))
print(".. :  "..tostring(myTable4 .. myTable5))

输出结果:

+ : 3
- : -1
* : 2
/ : 0.5
% : 1
^ : 1
== : false
< : true
<= : true
.. : 12

五、__index

__index:当子表中找不到某一个属性时,会到元表中 __index指定的表去找索引
示例代码(若子表中不含age属性):

meta = {}
myTable = {}
-- __index的赋值,最好写到表外面初始化
meta.__index = {age = 1}
setmetatable(myTable,meta)
print(myTable.age)

输出:

1

上面myTable.age是在myTable中没有age属性的情况下,去访问元表中的__index表;如果不想访问__index的表,需要绕过它,则需用到另一个函数rawget(table,index)

meta = {
	age = 1
}
myTable = {}
meta.__index = meta
setmetatable(myTable,meta)
print(myTable.age)
print(rawget(myTable,"age"))

输出结果:

1
nil

总结: 使用rawget方法访问age时,即使元表meta的__index已经包含age属性,也不会被访问到

六、__newindex

__newindex :当赋值时,如果赋值一个不存在的索引,那么会把这个值赋值到__newindex所指的表中, 不会修改自己
示例代码:

meta = {}
meta.__newindex = {}
myTable = {}
setmetatable(myTable,meta)
myTable.age = 1
print(myTable.age)
print(meta.__newindex.age)

输出结果:

nil
1

上面赋值时,是将值赋值到元表meta的__newindex中,如果要将值赋值到myTable中,则需使用rawset(table,index,value)
示例代码:

meta = {}
meta.__newindex = {}
myTable = {}
setmetatable(myTable,meta)
rawset(myTable7,"age",2)
print(myTable.age)

输出结果:

2

总结: 使用rawset方法赋值age时,是直接将值赋到myTable,不会访问__newindex

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值