BeWithYou

胡搞的技术博客

  1. 首页
  2. C/C++/Lua
  3. Lua学习笔记(五)

Lua学习笔记(五)


面向对象:

Lua中隐藏了self的语法糖。用冒号隐藏了第一个参数self。

function A:fun(v)
    self.name = v
end
a:fun(100)


类:

Lua中没有类的概念,只有对象。但是我们可以通过metatable继承的方式,实现prototype,从达到类的效果。简单的说,setmetatable(a, {__index = b}) 将b对象设为a的prototype。a可以看做对象,b看做类。

一般创建一个对象的方法:

function seat:new(o)
    o = o or {}
    o.param = 0 --初始化一些内部的变量等
    setmetatable(o,self) --设置新对象o的prototype为seat本身
    self.__index = self
return o
end
local seat_obj = seat:new() --得到一个seat类的对象
seat_obj:other_fun(xx) -- 调用seat类的方法


继承:

seat_obj = seat:new()
s = seat_obj:new({name="hehe”})

seat_obj从seat继承了new方法,new执行的时候self其实是seat_obj。这样s继承了seat_obj,可以访问seat_obj和seat中的方法。

继承之后,还可以重写从父类中继承的方法。


多重继承:

当一个表的metatable中__index为一个函数时,如果调用了一个不存在的函数,则会去调用__index指定的函数。

local function search(k,plist)
    for i,v in pairs(plist) do
        print (i,v)
        local j =v[k]
        if j then return j end
    end
end
function createclass(...)
    local c = {}
    local param = {…} -- 把各个父类包成table传下去
    -- t对象 k方法名
    setmetatable(c, {__index = function (t,k) return search(k,param) end})
    c.__index =c
    function c:new(o)
        o = o or {}
        setmetatable(o,c)
        return o
    end
    return c
end
A = {}
function A:getname()
    return self.name
end
B = {}
function B:getage()
    return self.age
end
T = createclass(A,B)
a = T:new({name="hehe",age="24"})
print(a:getname())
print(a:getage())

-- output
1table: 0x7fa171c0a4b0
hehe
1table: 0x7fa171c0a4b0
2table: 0x7fa171c0a4f0
24


私有性:

Lua本身不提供对象成员的私有性访问。因为它是用通用数据结构table来表示对象的。

但还是有解决方案的,虽然不会用到。

在工厂函数里用局部变量self表示对象local self = {name = “hehe”},用local的函数为对象的每个方法创建闭包。最后将这些函数打包返回给外部。如此,生成的对象只能调用暴露给外部的方法,不能直接访问闭包内的方法和成员变量了。需要注意的时,用的时候不可以加冒号,因为不依赖对象本身self。


single-method对象
对象只有一个单一的方法。可以将此方法当做对象返回。

function newObject(value)
   return function (action ,v)
       if action == “get” then return value
       elseif action == “set” then value = v
       else error(“invalid action”)
       end
   end
end
d = newObject(0)
print(d(“get”)) — 0
d(“set”,10)
print(d(“get”)) — 10

入参居然可以当做私有变量保存在闭包里,好神奇。

Weak表与垃圾回收:
Lua自动进行内存管理。程序只能创建不能删除(表,函数等)。Lua会自动删除失效的内容。Lua 中所有用到的内存,如:字符串、表、用户数据、函数、线程、 内部结构等,都服从自动管理。
任何在全局中声明的对象,lua都不认为是垃圾。需要自己手动设为nil来清除。
Weak表用来告诉lua一个引用不应该防止对象被回收。一个wak table是指所有引用都指向weak的table。如果一个对象只存在于weak table中,最终它将会被回收。
lua不会收集作为key和value的table。表的weak性有metatable中的__model指定。__model包涵字符k时 key是weak的,包含字符v时value是weak的。设置了以后,一旦发现没有引用的key或value则会回收掉。
我们使用collectgarbage “count” 获取程序消耗的内存KB。
我们使用collectgarbage “collect” 强制执行垃圾回收。
collectgarbage还有其他的参数选项,可以用于设定回收间歇率,步进倍率,停止,重启等等。

   


回到顶部