Lua-- 元表

print("******* Metatable *******")
-- print("******* 元表概念 *******")
-- 任何表变量都可以作为另一个表变量的元表
-- 任何表变量都可以有自己的元表(父表)
-- 当我们的子表中进行一些特定操作时
-- 会执行元表中的内容
-- print("******* 设置元表 *******")
meta = {}
myTable = {}
-- 设置元表函数
-- 第一个参数:子表
-- 第二个参数:元表
setmetatable(myTable, meta)

-- print("******* 特定操作 *******")
-- print("******* 特定操作-__tostring *******")
meta2 = {
    -- 当子表要被当作字符串使用时,会默认调用这个元表中的__tostring方法
    __tostring = function ()
        return "Mr.z"
    end
}
myTable2 = {}
setmetatable(myTable2, meta2)
-- 会执行 meta2 表中的 __toString 操作
print(myTable2)

meta3 = {
    -- __tostring 传入参数默认将关联的表传入
    __tostring = function (t)
        return t.name
    end, -- 注意这里有一个 逗号

    -- 当子表被当作一个函数来使用时,会默认调用元表中的 __call 中的内容
    -- 参数表中的第一个参数默认为 调用的子表 自己,类似于 : 的用法
    __call = function (a, b)
        print(a, b)
        print("In __call")
    end
}
myTable3 = {
    name = "Miss.Z"
}
setmetatable(myTable3, meta3)
print(myTable3)

-- print("******* 特定操作-__call *******")
-- 只有在元表中实现了 __call 才能将表当作函数调用
myTable3(1)

-- print("******* 特定操作-_运算符重载 *******")
meta4 = {
    -- 相当于运算符重载,当子表使用 + 运算符时,会调用该方法
    -- 重载运算符 +
    -- a + b, t1 表示 a, t2 表示 b
    __add = function (t1, t2)
        print(t1.age, t2.age)
        return t1.age + t2.age
    end,
-- 运算符 -: __sub
-- 运算符 *: __mul
-- 运算符 /: __div
-- 运算符 %: __mod
-- 运算符 ^: __pow
-- 运算符 ..(拼接): __concat
-- 运算符 ==: __eq
    __eq = function (t1, t2)
        return true;
    end
-- 运算符 <: __lt
-- 运算符 <=: __le
-- 注意:条件运算符没有 !=, >, >=, 只能通过 not 取反, 但实际上不需要,
-- 因为 t1 > t2 相当于 t2 < t1,也是重载 <
--(这也是两个对象的元表一定要一致才能正确使用条件运算符的原因)
}
-- 也可以元表外声明
meta4.__sub = function (t1, t2)
    print("in __subs");
end

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

print(myTable4 + myTable5)
print(myTable4 - myTable5)

-- 如果要用条件运算符来比较两个对象
-- 这两个对象的元表一定要一致,才能准确调用方法
print(myTable4 == myTable5)     -- false
setmetatable(myTable5, meta4)
print(myTable4 == myTable5)     -- true

-- print("******* 特定操作-__index 和 __newindex *******")
meta5 = {
    age = 1,
    __index = {age = 2}
    -- __index = meta5     -- 这是个坑,会返回 nil,所以建议 __index 写在表外
}
-- meta5.__index = {age = 4}
-- meta5.__index = meta5

myTable6 = {}
setmetatable(myTable6, meta5)
-- __index 当子表中找不到某一个属性时
-- 会到元表中 __index 指定的表去找索引
print(myTable6.age)

-- __index 可以嵌套
meta6Father = {age = 2}
meta6 = {}
myTable7 = {}

meta6.__index = meta6Father
setmetatable(myTable7, meta6)
setmetatable(meta6, meta6Father)
print(myTable7.age)

-- __newIndex 当赋值时,如果赋值一个不存在的索引
-- 那么会把这个值赋值到 __newindex 所指的表中,不会修改自己
meta7 = {}
myTable8 = {}
setmetatable(myTable8, meta7)
myTable8.age = 1
print(myTable8.age)   -- age 添加在 myTable8 中,输出为1

meta7.__newindex = {}
myTable8.name = "name"
-- name 添加在元表的__newindex指向的表中,myTable8 中没有该变量,输出为 nil
-- 否则需要设置 meta7.__index = meta7.__newindex 才可通过 myTable8 获得 name 变量
print(myTable8.name)
print(meta7.__newindex.name)
-- newindex 与 index 类似可以嵌套

-- 如果只想知道自己身上有没有这个变量忽略 __index,那么可以使用 rawget
-- 如果有返回该变量的值,否则返回 nil
print(rawget(myTable8, "age"))
print(rawget(myTable8, "name"))
-- 如果只想对自己的表进行修改忽略 __newindex 设置 ,可以对应使用 rawset
rawset(myTable8, "name", "selfName")
print(myTable8.name)

-- 其他
-- 获取元表
print(getmetatable(myTable8))

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值