Lua 初识之 self this
Lua 中面向对象是使用 table 实现的。
认识 self、this
– 指定一项操作的“接受者”,添加一个额外的参数来表示接受者,这个参数通常称为 self 或者 this
local Data = {num = 1}
--- 使用冒号定义函数,默认需要将 Data 作为第一个参数传递进来作为 self 使用
function Data:Add(value)
--- self 就是 Data 自身
if type(self) == "number" then
print("self is number:"..tostring(self))
end
self.num = self.num + value
print("Add num:"..self.num)
end
--- 使用冒号调用,默认需要将 Data 作为第一个参数,传递进 Add 函数
--- 此时 Add 函数中
--- Data 传递给 self
--- 5 则传递给 value
Data:Add(5)
--- 使用逗号调用,需要将 Data 作为第一个参数传递进去,否则会报错
--- 此时 Add 函数中
--- Data 传递给 self
--- 10 则传递给 value
Data.Add(Data, 10)
-- 如下调用报错
-- 此时 Add 函数中
--- 15 传递给 self,此时 self 就是 15 了,而不是 Data
--- value 参数则为 nil
Data.Add(15)
下方是输出结果
Add num:6
Add num:16
self is number:15
lua: .code.tio:10: attempt to index a number value (local 'self')
stack traceback:
.code.tio:10: in field 'Add'
.code.tio:37: in main chunk
[C]: in ?
从输入日志可以看出
调用 Data:Add(5) 输出了:Add num:6
调用 Data.Add(Data, 10) 输出了:Add num:16
Data.Add(15) 首先输出了:self is number:15,也就是说此时 self 的类型判断是 number,也就是此时 self 就是 15
使用冒号定义的函数:
使用冒号方式调用:Data:Add(5)
使用点方式调用: Data.Add(Data, 10)
区别就是:1 冒号调用,默认将 Data(自己作为第一个参数传递进去)
2 逗号调用需要将所有参数都传递进去
修改代码
local Data = {num = 20}
--- 使用 点 定义函数,函数有几个参数就要传递进来几个
function Data.Sub(self, v)
self.num = self.num - v
print("Sub num:"..self.num)
end
--- 使用 点 定义函数,函数有几个参数就要传递进来几个
function Data.Sub2(self, v)
--- 此时的 self 并不一定是 Data,调用 Sub2 的时候,传递进来的第一个参数就是 self
self.num = self.num - v
print("Sub2 num:"..self.num)
end
--- 使用 点 调用函数, Data 作为第一个参数传递给 Sub 函数的 self
--- 2 作为 第二个参数传递给 第二个参数 v
Data.Sub(Data, 2)
--- 使用冒号调用,默认将Data作为第一个参数传递个 Sub 函数的 self
--- 10 作为 第二个参数传递给第二个参数 v
Data:Sub(10)
--- 使用 点 调用, Tree 作为第一个参数,传递个 Sub2 函数的 self
--- 5 作为第二个参数传递给 第二个参数 v
--- 所以此时 Sub2 函数中的 self 其实就是 Tree
local Tree = {num = 1000}
Data.Sub2(Tree, 5)
--- 下面是输出结果
Sub num:18
Sub num:8
Sub2 num:995