前情提示
本篇文章参考了其他文章,然后自己通过实例进行测试总结;自己作为一个初学者尚有考虑不到的地方,如果文章有错误,希望大佬们指点
参考1:Lua函数传递self的深入理解
参考2:Lua中的self
实例1,方法调用中的self和.
--second.lua
local second = {
}
function second:funcA()
self.secondNum = 3
end
return second
--first.lua
local second = require("Scripts/Test/second")
local first={
}
function first:funcB()
second.funcA(self)
print(self.firstNum)
print(self.secondNum)
print(first.firstNum)
print(first.secondNum)
print(second.firstNum)
print(second.secondNum)
end
first.firstNum = 5
first:funcB()
return first
打印截图如下
大致过程:first.lua文件在引入second模块后,创建表,为first表创建属性并赋值5,之后调用方法funcB,然后second模块调用funcA并传入self
根据打印的结果,很容易就知道self传入的是first的self而不是second的self,所以将first的self传入second的funcA方法中导致了first多了一个secondNum属性且其值为3;而且还能知道显示的self在哪个模块,那么它就代指哪个模块,我将它理解为C#中的this关键字
另外,将funcA()改为funcA(…)打印的结果也是一样的,所以如果考虑要传入参数最好还是在方法中加入(…)作为一种规范
实例2,方法调用中的self和:
现在我们将调用funcA的".“改为”:",second.lua文件不改
--first.lua
local second = require("Scripts/Test/second")
local first={
}
function first:funcB()
second:funcA() --更改的地方
print(self.firstNum)
print(self.secondNum)
print(first.firstNum)
print(first.secondNum)
print(second.firstNum)
print(second.secondNum)
end
first.firstNum = 5
first:funcB()
return first
打印结果如下
从打印中可以清楚地看到最后一行打印是有值的,说明如果使用":“去调用方法的话,其实会隐式地传入self,这个self就是指”:"之前的那个对象(这里是second)
实例3,方法定义中的self
现在我们只改first.lua文件中的方法定义
--first.lua
local second = require("Scripts/Test/second")
local first={
}
function first.funcB(self)
second.funcA(self)
print(self.firstNum)
print(self.secondNum)
print(first.firstNum)
print(first.secondNum)
print(second.firstNum)
print(second.secondNum)
end
first.firstNum = 5
first.funcB(first)
return first
打印结果
你发现了吗?打印的结果和实例1是一模一样的;方法定义有self,而方法体内也有self作为实参,这个时候实例三的方法定义中的self相比实例1就没有多大意义了,还容易混淆,不如实例1更简洁
个人总结:
1.self通常不放在函数定义中,因为产生不了太大作用
2.需要注意":“与隐式的self对应,”.“与显示的self对应的作用不同;如second.funcA(self)不等同于second:funcA(),而second:funcA()与second.funcA(second)是等价的;只要记住self基本等同于其他语言的this即可
3.在规范和简洁的方向上,显然用”:“调用方法比”.“调用方法更简洁高效,如果两者使用产生同等作用时,用”:“来调用就行;而且在原理上”:"调用确实更快,具体可以看我在前情提示中的参考2的文章