test.lua
local test = {} --定义一张table
test.name = "测试者"
function test:sayHiTo(person)
return self.name .. "say hi to "..person
local callTest = {}
callTest.testFunc = test.sayHiTo
print(callTest.testFunc("jason"))
-----------------------
结果报错:
stdin:1: attempt to concatenate local 'person' (a nil value)
stack traceback:
stdin:1: in function 'test'
stdin:1: in main chunk
[C]: ?
----------------------
错误的原因是 test:sayHiTo(person)等价于test.sayHiTo(test,person),这里其实是两个入参,但是调用callTest.testFunc("jason") 等价于 test.sayHiTo("jason"),这里只有一个入参,所以无法找到'person'这个参数值
----------------------
当然你可以尝试自己随便传第一个参数如:
callTest.testFunc("默认参数","jason")
-------------------------------------
结果还是报错:
stdin:1: attempt to concatenate field 'name' (a nil value)
stack traceback:
stdin:1: in function 'test'
stdin:1: in main chunk
[C]: ?
-------------------------------------
为什么,因为"默认参数"并没有name属性。
-------------------------------------
那是不是可以给第一个参数增加name属性就ok呢?
local extra = {}
extra.name = "哈哈"
print(callTest.testFunc(extra,"jason"))
-------------------------------------
结果输出:哈哈say hi to jason
没报错。
所以self就是指代传进来的第一个参数。
-------------------------------------
那怎么把test作为第一个参数传进去呢?
在同一个文件里是可以直接取到test变量的,可以直接这样做:callTest.testFunc(test,"jason")
那要是在不同文件里去调test的方法呢?因为test是定义成local的,所以作用域是在所属的test.lua文件
-------------------------------------
我们可以再包装一层,lua的引用可以是变量,可以是函数,都可以
那么我们这样封装一下:
local function createInovation(target,method)
return function(...) return method(target, ...)
end
callTest.testFunc = createInovation(test,test.sayHiTo)
这样就可以正常使用了
createInovation()方法主要是重新构建一个函数,这个函数返回带第一个参数是target的函数