Lua中如何将对象作为回调参数传递

定义View和ViewGroup类,View的onDraw方法可以自定义,遍历ViewGroup中的所有View对象,执行其onDraw方法,并将Canvas对象传递给onDraw方法。

在View的onDraw中不能调用Canvas的方法,也不能使用self来调用View中的属性,但可以保证Canvas对象正确。示例如下:

ViewGroup = {
  childcount = 0,
  childs = {} -- view object list
}

function ViewGroup:onDraw(canvas)
    for i=1,self.childcount do
          local childView = self.childs[i]
          childView:onDraw(canvas)
    end
end

View = {
    x = 0,
    y = 0,
    width = 0,
    height = 0,
    onDraw = nil
}

function View:new()
    local o = {
        onDraw = nil
    }
    setmetatable(o, self)
    self.__index = self
    return o
end

button1 = View:new()
button1.onDraw = function(canvas)
   -- 这里的问题在于不能调用Canvas的方法也不能调用self.width
    canvas:save()
    canvas:fillRect(0, 0, self.width, self.height)
    canvas:restore()
end

错误提示:

尝试调用一个空值(方法“save”)
尝试索引一个空值并且(全局“self”)
点赞
用户752976
用户752976

你正在使用点号( .)语法声明回调函数:

button1.onDraw = function(canvas)

但是你正在使用冒号( :)来调用它:

childView:onDraw(canvas)

第二种调用约定意味着第一个传入的参数将是“self”,或者在你的特定情况下,它等价于:

childView.onDraw(childView, canvas)

为了解决这个问题,要么将按钮的 onDraw 改为使用 :

function button1:onDraw(canvas)

或者像 Egor 建议的那样手动添加 self 参数:

button1.onDraw = function(self, canvas)
2018-01-17 13:29:54