• Lua笔记


    只是为了防止忘记而写的记录。

    1.表的构造,所有的索引值都必须用[ ]表示,如果是字符串,可以去掉引号和中括号

    2.  a and b  如果a为 false,返回a,否则b

         a or b 如果a为真,返回a,否则b

    3.

      1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      2 --倒置的链表
      3 list  = nil
      4 for i = 1, 10 do
      5     list = { next = list, value = i}
      6 end
      7 
      8 local l = list
      9 while l do
     10     print(l.value)
     11     l = l.next
     12 end
     13 
     14 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     15 --队列
     16 List = {}
     17 function List.new()
     18     return {fisrt = 0, last = 0}
     19 end
     20 function List.push(Q,value)
     21     local last = Q.last + 1
     22     Q[last] = value
     23     Q.last = last
     24 end
     25 
     26 function List.pop(Q)
     27     local first = Q.first + 1
     28 
     29     if first > Q.last then return error("error") end
     30     Q.first = first
     31     return Q[first-1]
     32 end
     33 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     34 串行化:
     35 function serialize(o)
     36     if type(o) == "number" then
     37         io.write(o)
     38     elseif type(o) == "string" then
     39         --string.format函数的"%q"参数可以转义字符串中的元字符。
     40         io.write(string.format("%q",o))
     41     elseif type(o) == "table" then
     42         io.write("{
    ")
     43         --迭代table中的各个元素,同时递归的写出各个字段的value。
     44         --由此可以看出,这个简单例子可以支持嵌套的table。
     45         for k,v in pairs(o) do
     46             --这样做是为了防止k中包含非法的Lua标识符。
     47             io.write(" ["); serialize(k); io.write("] = ")
     48             serialize(v)
     49             io.write(",
    ")
     50         end
     51         io.write("}
    ")
     52     else
     53         error("cannot serialize a " .. type(o))
     54     end
     55 end
     56 
     57 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     58 元表的应用:
     59 Set = {}
     60 local mt = {}
     61 
     62 function Set.new(L)
     63     local set = {}
     64     setmetatable(set,mt)
     65     for _,v in pairs(L) do
     66         set[v] = true
     67     end
     68     return set
     69 end
     70 
     71 function Set.union(a,b)
     72     local cur = {}
     73     for i in pairs(a) do
     74         cur[i] = true
     75     end
     76 
     77     for i in pairs(b) do
     78         cur[i] = true
     79     end
     80     return cur
     81 end
     82 
     83 function Set.intersection(a,b)
     84     local cur = {}
     85     for v in pairs(a) do
     86         cur[v] = b[v]
     87     end
     88     return cur
     89 end
     90 
     91 function Set.tostring(set)
     92     local l = {}
     93     for e in pairs(set) do
     94         l[#l+1] = e
     95     end
     96     return "{"..table.concat(l,",").."}"
     97 end
     98 
     99 function Set.print(s)
    100     print(Set.tostring(s))
    101 end
    102 
    103 mt.__add = Set.union
    104 
    105 s1 = Set.new({10,20,30,50})
    106 s2 = Set.new({15,25,35,60})
    107 
    108 s3 = s1+s2
    109 Set.print(s3)
    110 
    111 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    112 __newindex元方法与__index类似,__newindex用于更新table中的数据,
    113 而__index用于查询table中的数据。当对一个table中不存在的索引赋值时,在Lua中是按照以下步骤进行的:
    114 1.Lua解释器先判断这个table是否有元表;
    115 2.如果有了元表,就查找元表中是否有__newindex元方法;如果没有元表,就直接添加这个索引,然后对应的赋值;
    116 3.如果有这个__newindex元方法,Lua解释器就执行它,而不是执行赋值;
    117 4.如果这个__newindex对应的不是一个函数,而是一个table时,Lua解释器就在这个table中执行赋值,而不是对原来的table。
    118 
    119 __index 例子:
    120 Windows = {}
    121 
    122 Windows.default = {
    123     x = 0,y = 0,with = 100,heigh = 200,
    124     color = {
    125         r = 255, g = 255, b = 255
    126     }
    127 }
    128 
    129 function Windows.tostring(s)
    130     if type(s) == "number" then
    131         io.write(s)
    132     elseif type(s) == "string" then
    133         io.write(string.format("%q",s))
    134     elseif type(s) == "table" then
    135         io.write("{")
    136         for key,value in pairs(s) do
    137             io.write("["); io.write(Windows.tostring(key)); io.write("] = ")
    138             io.write(Windows.tostring(value))
    139             io.write(",
    ")
    140         end
    141         io.write("}")
    142     else
    143         error("cannot tostring!!!");
    144     end
    145 end
    146 
    147 function Windows.print(s)
    148     return print(Windows.tostring(s))
    149 end
    150 Windows.mt = {} -- 创建元表
    151 
    152 function Windows.new(o)
    153     setmetatable(o,Windows.mt)
    154     return o
    155 end
    156 
    157 Windows.mt.__index = function (table ,key)
    158     return Windows.default[key]
    159 end
    160 
    161 local win = Windows.new{x = 10, y = 20 }
    162 
    163 
    164 Windows.print(win.x)
    165 Windows.print(win.with)
    166 Windows.print(win.color)
    167 
    168 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    169 实现类和对象的例子:
    170 p中有没有talk这个键? 有 --> 返回talk对应的值
    171         |
    172        没有
    173         |
    174 p中是否设置过metatable? 否 -->  返回nil
    175         |
    176 177         |
    178 在p的metatable中有没有__index这个键? 没有 -->  返回nil
    179         |
    180 181         |      
    182 在p的metatable中的__index这个键对应的表中有没有talk这个键? 没有 --> 返回nil
    183         |
    184         有,返回getmetatable(p).__index.talk
    185         
    186         
    187 Person = {name = "我是一个懒人"} --
    188 
    189 Person.__index = Person --重定义元表的索引  设置Person类的__index为自己
    190 function Person:talk(words)--类的一个方法
    191     print(self.name.." 说:"..words)
    192 end
    193 
    194 function Person:create(name)--构造函数一样
    195     local p = {}
    196     setmetatable(p,Person) --设置了p的元方法
    197     p.name = name
    198     return  p
    199 end
    200 
    201 local pa = Person:create("路人甲A") --创建一个对象
    202 local pb = Person:create("路人甲B")
    203 
    204 pa:talk("hello")
    205 pb:talk("sb")
    206 
    207 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    208 类的继承的一个例子:必须理解setmetatable,__index的过程。
    209 
    210 -- http://blog.csdn.net/losophy/article/details/20311387
    211 A  = {} --基类A
    212 
    213 function A:new(o) --构造方法
    214     o = o or {} --如果为nil 则赋值为{}
    215     setmetatable(o,self) --设置元方法,确定在谁那寻找子类,没有的方法
    216     self.__index = self --这个很重要。所以理解。
    217     return o
    218 end
    219 
    220 function A:funName()
    221     print("A")
    222 end
    223 
    224 B = A:new()
    225 B:funName()
    226 
    227 C = B:new()
    228 
    229 function B:funName()
    230     print("B")
    231 end
    232 
    233 C:funName()
    234 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    235 使用__newindex设置只读模式,牛气
    236 local function readOnly(t)
    237     local newT = {}
    238     local mt = {
    239         __index = t,
    240         __newindex = function()
    241             error("别修改我!我是只读的!")
    242         end
    243     }
    244     setmetatable(newT, mt)
    245     return newT
    246 end
    247 local days = readOnly({"星期一", "星期二", "星期日"})
    248 
    249 print(days[2])
    250 days[1]="hehe" --但调用次赋值的时候,就会找到__newindex,从而被禁止 
    251 
    252 ______________________________________________________________
    253 a.首先,readOnly会创建一个新的table,然后把我们传进去的table作为__index元方法。
    254 b.元表里还增加了__newindex,用来阻止不存在字段的赋值操作。
    255 c.readOnly返回的table已经不是我们原来的table了,它是一个空的table,但是它被设置了一个新的元表。
    256 d.开始对days执行赋值操作:days[2] = “星期三哪去了啊?” 。
    257 e.days是一个空的table,所以它不存在这个字段,也因此,会调用__newindex元方法,赋值失败。
    258 f.如果只是调用days,不进行赋值,如:print(days[2]); 则能正常输出字段值,因为days的元表里有__index元方法。虽然days中不存在2这个字段,但是可以通过__index找到这个字段。
    259 总而言之,最终,days成为了一个只可以读取,不能进行赋值操作的table。
    260 
    261 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    262 解释__newindex的作用
    263 a.如果__newindex是一个函数,则在给table不存在的字段赋值时,会调用这个函数。
    264 b.如果__newindex是一个table,则在给table不存在的字段赋值时,会直接给__newindex的table赋值。
    265 
    266 local smartMan = {
    267     name = "hxl",
    268     money = 9000,
    269     hello = function()
    270         print("hxl ni hao")
    271     end
    272 }
    273 
    274 local t = {}
    275 
    276 local mt = {
    277     __index = smartMan,
    278     __newindex = function(table,key,value)
    279         print("key".."不要试图修改我,已经被禁止了!")
    280     end
    281 }
    282 
    283 setmetatable(t,mt)
    284 
    285 print(t.name)
    286 print(t.money)
    287 t.hello()
    288 t.hello = "heh"
    289 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    290 __index 和 __newindex的一个很牛气的例子
    291  local smartMan = {
    292         name = "none",
    293     }
    294    
    295     local other = {
    296         name = "大家好,我是很无辜的table"
    297     }
    298    
    299     local t1 = {};
    300    
    301     local mt = {
    302         __index = smartMan,
    303         __newindex = other
    304     }
    305    
    306     setmetatable(t1, mt);
    307      
    308     print("other的名字,赋值前:" .. other.name);
    309     t1.name = "小偷";
    310     print("other的名字,赋值后:" .. other.name);
    311     print("t1的名字:" .. t1.name);
    312 结果:
    313 [LUA-print] other的名字,赋值前:大家好,我是很无辜的table
    314 [LUA-print] other的名字,赋值后:小偷
    315 [LUA-print] t1的名字:none
    316 说明:修该的时候只会修改__newindex里面的指定的地方值,
    317       查询的时候只会读出 __index里面的值.
    318 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    View Code

    4.

      1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      2 Lua实现多重继承:
      3 
      4 
      5  function search(classes, key)--查询函数
      6     for i = 1, #classes do
      7         local value = classes[i][key];
      8         if value ~= nil then
      9             return value;
     10         end
     11     end
     12 end
     13 
     14  function createClass(...) --可变参数
     15     local parents = {...}; --保存它的可变参数
     16     local child = {};
     17 
     18     -- 设置类的元表,如果元表已经设置,就去元表里看看有没有设置__index,找有没有对应的key值.
     19     setmetatable(child, {
     20         __index = function(table, key)
     21             return search(parents, key);
     22         end
     23     })
     24 
     25     -- 给类新增一个new函数,用于创建对象
     26     function child:new()
     27         o = {};
     28         setmetatable(o, child);--设置元表,并且在自己的地方寻找有木有相对于的key值
     29         child.__index = child;--设置元表,并且在自己的地方寻找有木有相对于的key值
     30         return o;
     31     end
     32 
     33     -- 返回这个继承了多个类的子类
     34     return child;
     35 end
     36 
     37 
     38  --一个精灵类
     39     TSprite = {}
     40     function TSprite:hello()
     41         print("谁跟你hello!");
     42     end
     43 
     44     function TSprite:new()
     45         o = {}
     46         setmetatable(o, self);
     47         self.__index = self;
     48         return o;
     49     end
     50 
     51     -- 一个子弹类
     52     TBullet = {}
     53     function TBullet:fire()
     54         print("别动,再动我就瞄不准了!");
     55     end
     56     function TBullet:new()
     57         o = {}
     58         setmetatable(o, self);
     59         self.__index = self;
     60         return o;
     61     end
     62 
     63     -- 继承了两个类的子类
     64     local BulletSprite = createClass(TSprite, TBullet);--传入这两个table,返回对应的child
     65 
     66     -- 子类的对象
     67     local bSprite = BulletSprite:new();
     68     bSprite:hello();
     69     --[[子类对象调用hello方法,会去bSprite中寻找,
     70     发现没有,那么此时没有就去看看 bSprite有没有设置元表有的,去元表中看有没有设置__index
     71     发现也是有的,就调用它对应的方法,便进入了serch了。便可以找到了
     72     --]]
     73     bSprite:fire();
     74 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     75 弱引用:
     76 1)key值弱引用,也就是刚刚说到的情况,只要其他地方没有对key值引用,
     77 那么,table自身的这个字段也会被删除。设置方法:setmetatable(t, {__mode = “k”});
     78 2)value值弱引用,情况类似,只要其他地方没有对value值引用,
     79 那么,table的这个value所在的字段也会被删除。设置方法:setmetatable(t, {__mode = “v”});
     80 3)key和value弱引用,规则一样,但是key和value都同时生效,
     81 任意一个起作用时都会导致table的字段被删除。设置方法:setmetatable(t, {__mode = “kv”});
     82  
     83 当然,这里所说的被删除,是指在Lua执行垃圾回收的时候,并不一定是立刻生效的。
     84 我们刚刚只是为了测试,而强制执行了垃圾回收。
     85 
     86 t = {};
     87 
     88     -- 给t设置一个元表,增加__mode元方法,赋值为“k”
     89     setmetatable(t, {__mode = "k"});
     90 
     91     -- 使用一个table作为t的key值
     92     key1 = {name = "key1"};
     93     t[key1] = 1;
     94 
     95     -- 又使用一个table作为t的key值
     96     key2 = {name = "key2"};
     97     t[key2] = 1;
     98 
     99     t = {}
    100     key1,key2 = t,t
    101 
    102     -- 强制进行一次垃圾收集
    103     collectgarbage();
    104 
    105     for key, value in pairs(t) do
    106         print(key.name .. ":" .. value);
    107     end
    108 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    View Code
  • 相关阅读:
    装饰器模式(Decorator)
    原语:从0到1,从硬件指令集到OS原语,锁原语的哲学
    从Oop-Klass模型看透反射
    从三数之和看如何优化算法,递推-->递推加二分查找-->递推加滑尺
    单例模式-静态内部类实现及原理剖析
    单例模式-DCL双重锁检查实现及原理刨析
    二分查找java实现
    I/O管理杂记
    PCB WCF Web接口增减参数后,在客户端不更新的情况,是否影响客户端,评估测试
    PCB MS SQL 排序应用(row_number rank dense_rank NTILE PARTITION)
  • 原文地址:https://www.cnblogs.com/tom987690183/p/4353591.html
Copyright © 2020-2023  润新知