Lua元表代码疑问:函数如何访问表字段 两次tb.new调用是否有差异
理解偏差纠正
你之前的执行逻辑理解有两处错误:
- 调用
tb.new("W")时,执行逻辑是创建一个全新的局部空表super,给这个新表的s字段赋值为传入的字符串"W",不是super.W = W - 每次调用
tb.new时,函数内部的super都是本次调用独有的局部变量,两次调用生成的是两个完全独立的表,分别赋值给了f和t,不存在print(super+super)的情况,实际执行的是print(f + t)
问题1解答
当Lua执行f + t的加法操作时,会按以下逻辑执行:
- 先检查加法操作的左操作数
f有没有元表,元表里有没有__add元方法 - 找到
f的元表meta里的__add对应的函数tb.add,自动把左操作数f、右操作数t作为参数传给tb.add,也就是等价于调用tb.add(f, t) tb.add的形参s1接收的是实参f(也就是第一次调用tb.new生成的表),形参s2接收的是实参t(也就是第二次调用tb.new生成的表)- 访问
s1.s就是访问f表的s字段(值为"W"),访问s2.s就是访问t表的s字段(值为"E"),拼接后返回"WE",就是最终打印的结果
问题2解答
两次setmetatable(super, meta)的调用有区别,也有共性:
- 共性:两次都是把同一个元表
meta绑定到目标表上,因此两个新生成的表f、t共享同一个元表的元方法,这也是Lua里面向对象实现中类方法复用的常见思路 - 区别:两次调用绑定的目标表
super完全不同,第一次是绑定到f对应的表,第二次是绑定到t对应的表,两个表是独立的内存对象,各自的s字段存储的值也互不影响
内容的提问来源于stack exchange,提问作者Xuer
相关产品推荐
相关产品推荐

