码农往事
我的代码为什么这么丑?一定是因为我长的不好看
posts - 29,comments - 86,trackbacks - 0
最近的工作主要涉及LUA,这有个坑必须记一下。
下面是一个LUA面向对象写法非常常见的写法。
Bird = {
    color = {};canFly = true
}

function Bird:new(o)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    self.color = {}
    return o
end
注意,这里Bird类有两个属性,1个表,1个是基本类型,然后上测试代码(Utils类只是简单的封装类,可以自己实现一个)
        local A = Bird:new()
        LoggerUtils:debug("------------------------------原始值-----------------------------------");
        LoggerUtils:debug("Bird canFly:" .. StringUtils.boolean2string(A.canFly));
        LoggerUtils:debug("Bird color:");
        CommonUtils.printTable(Bird.color)
        LoggerUtils:debug("a canFly:" .. StringUtils.boolean2string(A.canFly));
        LoggerUtils:debug("a color:");
        CommonUtils.printTable(A.color)
        --改变A的属性
        A.canFly = false
        A.color[1] = "red"
        A.color[2] = "blue"
        A.color[3] = "green"
        LoggerUtils:debug("------------------------------A改变后----------------------------------");
        LoggerUtils:debug("Bird canFly:" .. StringUtils.boolean2string(Bird.canFly));
        LoggerUtils:debug("Bird color:");
        CommonUtils.printTable(Bird.color)
        LoggerUtils:debug("A canFly after change:" .. StringUtils.boolean2string(A.canFly));
        LoggerUtils:debug("A color after chagne:");
        CommonUtils.printTable(A.color)
        LoggerUtils:debug("-------------------------------B的值----------------------------------");
        local B = Bird:new()
        LoggerUtils:debug("B canFly:" .. StringUtils.boolean2string(B.canFly));
        LoggerUtils:debug("B color:");
        CommonUtils.printTable(B.color)

代码执行结果:
2014-12-29 11:20:40,690 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: ------------------------------原始值-----------------------------------
2014-12-29 11:20:40,690 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: Bird canFly:true
2014-12-29 11:20:40,691 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: Bird color:
2014-12-29 11:20:40,691 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: a canFly:true
2014-12-29 11:20:40,691 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: a color:
2014-12-29 11:20:40,691 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: ------------------------------A改变后----------------------------------
2014-12-29 11:20:40,691 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: Bird canFly:true
2014-12-29 11:20:40,691 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: Bird color:
2014-12-29 11:20:40,692 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: 1:red
2014-12-29 11:20:40,692 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: 2:blue
2014-12-29 11:20:40,692 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: 3:green
2014-12-29 11:20:40,692 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: A canFly after change:false
2014-12-29 11:20:40,692 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: A color after chagne:
2014-12-29 11:20:40,693 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: 1:red
2014-12-29 11:20:40,693 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: 2:blue
2014-12-29 11:20:40,695 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: 3:green
2014-12-29 11:20:40,695 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: -------------------------------B的值----------------------------------
2014-12-29 11:20:40,695 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: B canFly:true
2014-12-29 11:20:40,695 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: B color:
2014-12-29 11:20:40,695 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: 1:red
2014-12-29 11:20:40,695 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: 2:blue
2014-12-29 11:20:40,696 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: 3:green
发现神马问题了吗?
当A的类型为表的属性color改变时,原始类的color属性也改变了,同时这个改变也影响到新建的B,而类型为基本类型的属性canFly就没有这个问题。
我的解决方法是新增一个set方法:
function Bird:setColor(color)
    self.color = color
end

然后修改改变属性的方式:
local color ={}
        color[1] = "red"
        color[2] = "blue"
        color[3] = "green"
        A:setColor(color)
输出结果:
2014-12-29 11:31:58,648 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: ------------------------------原始值-----------------------------------
2014-12-29 11:31:58,648 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: Bird canFly:true
2014-12-29 11:31:58,649 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: Bird color:
2014-12-29 11:31:58,649 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: a canFly:true
2014-12-29 11:31:58,649 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: a color:
2014-12-29 11:31:58,649 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: ------------------------------A改变后----------------------------------
2014-12-29 11:31:58,649 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: Bird canFly:true
2014-12-29 11:31:58,650 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: Bird color:
2014-12-29 11:31:58,650 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: A canFly after change:false
2014-12-29 11:31:58,650 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: A color after chagne:
2014-12-29 11:31:58,650 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: 1:red
2014-12-29 11:31:58,650 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: 2:blue
2014-12-29 11:31:58,650 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: 3:green
2014-12-29 11:31:58,651 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: -------------------------------B的值----------------------------------
2014-12-29 11:31:58,651 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: B canFly:true
2014-12-29 11:31:58,653 [main] DEBUG server.app.game.util.LoggerUtils:34 - LUA: B color:
另外同事一个解决方法更简单,直接修改new()方法,其它的地方都不用改:
function Bird:new(o)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    o.color = {} 
    return o
end
这个问题基本上网上的示例貌似都没提到,我读的书里也没有,实际调试过程中才发现的,会造成新创建的类里会有不该有的属性,比较蛋疼。
具体原因不了解,有木有筒子指教一下?顺便问问这两种方法哪种更好?
posted on 2014-12-29 11:42 Jimi 阅读(10759) 评论(5)  编辑  收藏 所属分类: LUA

FeedBack:
# re: LUA 面向对象编程中的一个坑
2014-12-29 16:53 | 威客
很厉害博主  回复  更多评论
  
# re: LUA 面向对象编程中的一个坑
2015-01-04 15:47 | flyforlove
你确定你写的测试程序没问题?  回复  更多评论
  
# re: LUA 面向对象编程中的一个坑
2015-01-05 09:39 | Jimi
@flyforlove
有问题麻烦请指出来  回复  更多评论
  
# re: LUA 面向对象编程中的一个坑
2015-01-30 18:27 | poetao
--改变A的属性
A.canFly = false
A.color[1] = "red"
A.color[2] = "blue"
A.color[3] = "green"
===改成如下就可以了===============
A.canFly = false
A.color = { "red", "blue", "green" }

===建议你详细看下元表的__index实现  回复  更多评论
  
# re: LUA 面向对象编程中的一个坑
2015-03-07 11:15 | Jimi
@poetao
多谢指教  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问