用冒号定义函数时,Lua 会自动给这个函数加上一个隐藏的第一个参数 self;self 指向调用该函数的那个表。obj:hello() 其实就是 obj.hello(obj)。
local obj = { name = "Tom" }
function obj:hello()
print(self.name) -- self 就是 obj 本身
end
obj:hello() -- 输出 Tom
如果改用点号定义函数,那么第一个参数就要自己写出来,名字可以叫 self,也可以叫别的,调用时手动把表传进去:
function obj.say(self)
print(self.name)
end
obj.say(obj) -- 把表当参数传进去
关键点:定义时用冒号,调用时也要用冒号,两边得对上。如果定义了 obj:hello(),却写成 obj.hello(),那么 self 就是 nil,一读 self.name 就会报错。
在模块里写方法也用这个套路:把模块表当 self,就能在函数内部用 self 拿到自己身上的其他字段和函数。