久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

lua程序設計第二版 讀書筆記(11

 quasiceo 2014-01-07
分類: Lua Lua 筆記 讀書筆記 第二版 lua程序 2013-05-11 15:14 176人閱讀 評論(0) 收藏 舉報

目錄(?)[+]

書本下載地址                       http://download.csdn.net/detail/myy2012/5349646

本部分下載地址                  http://download.csdn.net/detail/myy2012/5355935

 

 

lua程序設計第二版 讀書筆記(1-4章)
第一章 開始
第二章 類型與值
第三章 表達式
第四章 語句
http://blog.csdn.net/myy2012/article/details/8900424

lua程序設計第二版 讀書筆記(5-8章)
第五章 函數(shù)
第六章 深入函數(shù)
第七章 迭代器與泛型for
第八章 編譯執(zhí)行與錯誤
http://blog.csdn.net/myy2012/article/details/8906466

lua程序設計第二版 讀書筆記(9-10章)
第九章 協(xié)同程序
第十章 完整的實例
http://blog.csdn.net/myy2012/article/details/8911206

lua程序設計第二版 讀書筆記(11-14章)
第十一章 數(shù)據(jù)結(jié)構(gòu)
第十二章 數(shù)據(jù)文件與持久性
第十三章 元表metatable與元方法meatmethod
第十四章 環(huán)境
http://blog.csdn.net/myy2012/article/details/8914457

lua程序設計第二版 讀書筆記(15-17章)
第十五章 模塊與包
第十六章  面向?qū)ο缶幊?br> 第十七章 弱引用 table
http://blog.csdn.net/myy2012/article/details/8921632

lua程序設計第二版 讀書筆記(18-21章)
第十八章 數(shù)學庫
第十九章 table庫
第二十章 字符串庫
第二十一章 IO庫
http://blog.csdn.net/myy2012/article/details/8925895

lua程序設計第二版 讀書筆記(22-23章)
第二十二章 操作系統(tǒng)庫
第二十三章 調(diào)試庫
http://blog.csdn.net/myy2012/article/details/8930181

 

 

 

第十一章 數(shù)據(jù)結(jié)構(gòu)

table本身 就比數(shù)據(jù)和列表的功能強大的多,,因此許多算法都可以忽略一些細節(jié)問題,,從而簡化它們的實現(xiàn)。

11.1數(shù)組

使用整數(shù)來索引table即可在Lua中實現(xiàn)數(shù)組,。例如:

  1. a={}  
  2.   
  3. for  i = -5, 5 do   
  4.   
  5. a[i]=0  
  6.   
  7. end  


 

然而,,在Lua中的習慣一般是以1為數(shù)組的起始索引,,Lua庫和長度操作符都遵循這個預定。(如果你的數(shù)組不是從1開始的,,那就無法使用這些功能了)

11.2 矩陣與多維數(shù)組

Lua中,,有2中方式來表示矩陣。

第一種:使用“數(shù)組的數(shù)組”,,即一個table中的每個元素是另一個table

例如:

  1. mt={}  
  2.   for  i=1, N do   
  3.    for  j=1, M do  
  4.                  Mt[i][j] = 0  
  5. end  
  6.   end  

 

第二種:將2個索引合并為一個索引,。

例如:

  1. mt={}  
  2.       for i=1, N do  
  3. for j=1, M do  
  4. t[(i-1)+j]=0  
  5.              end   
  6. nd  


 

稀疏矩陣:大多數(shù)元素為0nil

11.3鏈表

由于table是動態(tài)的實體,,所以在Lua中實現(xiàn)鏈表是很方便的,。每個節(jié)點以一個table來表示,一個“鏈接”只是結(jié)點table中一個字段,,該字段包含了對其他table的引用,。

例如:

  1. list = nil   
  2.         list ={ next = list, value = v}  
  3.   local l=list  
  4.    <訪問 l.value>  
  5.   l=l.next  
  6. nd  


 

11.4 隊列與雙向隊列

 

  1. List={}  
  2. function List.new()  
  3.     return {first=0, last=-1}  
  4. end  


 

--------------

  1. function List.pushfirst(list, value)  
  2.     local first=list.first+1  
  3.     list.first=first  
  4.     list[first]=value  
  5. end  
  6. function List.pushlast(list, value)  
  7.     local last=list.last-1  
  8.     list.last=last  
  9.     list[last]=value  
  10. end  


 

---------------

  1. function List.popfirst(list)  
  2.     local first=list.first  
  3.     if first<list.last then  
  4.         error("list is empty")  
  5.     end  
  6.     local value=list[first]  
  7.     list[first]=nil  
  8.     list.first=first-1  
  9.     return value  
  10. end  
  11. function List.poplast(list)  
  12.     local last=list.last  
  13.     if list.first<last then  
  14.         error("list is empty")  
  15.     end  
  16.     local value=list[last]  
  17.     list[last]=nil  
  18.     list.last=last+1  
  19.     return value  
  20. end  


 

11.5 集合與無序組(bag

 

將集合元素作為索引放入一個table中,那么對于任意值都無須搜索table,,只需用該值來索引table,,并查看結(jié)果是否為nil

包,,有時候也稱為“多重集合”,,與普通的集合不同之處在于每個元素可以出現(xiàn)多次,。

11.6字符串緩沖

Lua中,我們可以使用函數(shù)table.concat將一個table作為字符串緩沖,,它會將給定列表中的所有字符串連接起來,,并返回連接的結(jié)果。

例如

  1.   local t={}  
  2.         for  line in io.lines() do  
  3. t[#t + 1] = line  
  4. end  
  5. local s = table.concat(t, “\n”)..”\n”  
  6.   
  7. a={"good", "girl", "bad", "boy"}  
  8. local s=table.concat(a)  
  9.   
  10. for k, v in ipairs(a) do  
  11.     print(k, v)  
  12. end  
  13. print(s)    --goodgirlbadboy  


 

11.7

接下來介紹一種簡單的面向?qū)ο蟮膶崿F(xiàn):結(jié)點表示為對象,、邊表示為結(jié)點間的引用,。

--根據(jù)給定的名稱返回對應的結(jié)點

  1. local function name2node(graph, name)  
  2.     if not graph[name] then  
  3.         graph[name]={name=name, adj={}}  
  4.     end  
  5.     return graph[name]  
  6. end  


 

-- 構(gòu)造圖

 

  1. function readgraph()  
  2.     local graph={}  
  3.     for line in io.lines() do  
  4.         local namefrom, nameto = string.match(line, "(%S+)%s+(%S+)")  
  5.         local from = name2node(graph, nameto)   -- 查找相應的結(jié)點  
  6.         from.adj[to] = true     -- 將“to“添加到”from“的鄰接集合  
  7.     end  
  8.     return graph  
  9. end  


 

-- 函數(shù)findpath采用深度優(yōu)先遍歷算法,在兩個結(jié)點間搜索一條路徑

-- 第一個參數(shù)是當前結(jié)點,,第二個參數(shù)是目標節(jié)點,,

-- 第三個參數(shù)用于保存從起點到當前結(jié)點的路徑,第四個參數(shù)是已訪問結(jié)點的集合

-- 【注意】該算法直接對結(jié)點進行操作,,而不是它們的名稱

 

  1. function findpath (curr, to, path, xisited)  
  2.     path = path or {}  
  3.     visited = visited or {}  
  4.     if visited[curr] then       --結(jié)點是否已訪問過?  
  5.         return nil              --這里沒有路徑  
  6.     end  
  7.     visited[curr] = true        --將結(jié)點標記為已訪問  
  8.     path[#path + 1] = curr      --將其加到路徑中  
  9.     if curr == to then          --最后的結(jié)點嗎,?  
  10.         return path  
  11.     end  
  12.     for node in pairs(curr.adj) do      --嘗試所有的鄰接結(jié)點  
  13.         local p = findpath(node, to, path, visited)  
  14.         if p then  
  15.             return p  
  16.         end  
  17.     end  
  18.     path[#path] = nil           -- 從路徑中刪除節(jié)點  
  19. end  


 

 

-- 測試上面所列函數(shù)

  1. function printpath(path)  
  2.     for i=1, #path do  
  3.         print(path[i].name)  
  4.     end  
  5. end  
  6.   
  7. g = readgraph()  
  8. a = name2node(g, "a")  
  9. b = name2node(g, "b")  
  10. p = findpath(a,b)  
  11.   
  12. if p then  
  13.     printpath (p)  
  14. end  


 

第十二章 數(shù)據(jù)文件與持久性

12.1 數(shù)據(jù)文件

將數(shù)據(jù)作為Lua代碼來輸出,當運行這些代碼時,,程序也就讀取了數(shù)據(jù),。而table的構(gòu)造式可以使這些輸出代碼看上去更像是一個普通的數(shù)據(jù)文件。

CSVComma-Separated Values 逗號分隔值):利用構(gòu)造式作為格式,。

自描述的數(shù)據(jù)(self-describing data):每項數(shù)據(jù)都伴隨一個表示其含義的簡短描述,。

Lua不僅運行速度快,,而且編譯速度快,。這不是偶然的結(jié)果,自從Lua創(chuàng)建之初就把數(shù)據(jù)描述作為Lua的主要應用之一來考慮的,,開發(fā)人員能較快地編譯大型程序投入了更多的努力,。

12.2串行化

通常需要串行化一些數(shù)據(jù),也就是將數(shù)據(jù)轉(zhuǎn)換為一個字節(jié)流或字符流,,然后就可以將其存儲到一個文件中,,或者通過網(wǎng)絡連接發(fā)送出去了。串行化后的數(shù)據(jù)可以用Lua代碼來表示,,這樣當運行這些代碼時,,存儲的數(shù)據(jù)就可以的讀取程序中得到重構(gòu)了。

編寫創(chuàng)建一個值的代碼,,方法如下:

  1. function serialize(o)  
  2.   if type(o) == “number” then  
  3.     io.write(o)  
  4.   elseif type(o) == “string” then  
  5.     io.write(string.format(“%q”, o))  
  6.   else   
  7.   <其他情況>  
  8.   end  
  9. end   


 

 

可以使用一個簡單且安全的方法來括住一個字符串,,那就是以“%q”來使用string.format 函數(shù)。這樣它就會用雙引號來括住字符串,,并且正確地轉(zhuǎn)移其中的雙引號和換行符等其他特殊字符,。

例如: 

  1. s=’a”problematic”\\string’  
  2. print(string.format(“%q”, s))  --"a\"problematic\"\\string"  


 

Lua 5.1還提供了另一種可以以一種安全的方法來括住任意字符串的方法:[=[...]=]

--查找最長的等號序列

  1. function quote(s)  
  2.     local n=-1  
  3.     for w in string.gmatch(s, "]=*") do  
  4.         n=math.max(n, #w-1)  
  5.     end  
  6.     local eq=string.rep("=", n+1)  
  7.     return string.format(" [%s[\n%s]%s] ", eq, s, eq)  
  8. end  
  9. print(quote("good]=girl bad=boy"))  

 

保存無環(huán)的table

保存有環(huán)的table

  1. function basicSerialize(o)  
  2.     if type(o) == "number" then  
  3.         return tostring(o)  
  4.     else  
  5.         return string.format("%q", o)  
  6.     end  
  7. end  
  8. print(basicSerialize(45))  
  9. print(basicSerialize('three'))  

 

第十三章 元表(metatable)與元方法(meatmethod

可以通過元表來修改一個值的行為,使其在面對一個非預定義的操作時執(zhí)行一個指定的操作,。例如:ab都是table,,通過元表可以定義如何計算表達式a+b,。

Lua試圖將兩個table相加時,它會先檢查兩者之一是否有元表,,然后檢查該元表中是否有一個叫_add的字段,;如果找到該字段,就調(diào)用該字段對應的值(即元方法),。

Lua中的每個值都有一個元表,。Tableuserdata可以有各自獨立的元表,而其他類型的值則共享所屬的單一元表,。

標準的字符串程序庫為所有的字符串都設置了一個元表

 

  1. t={}  
  2. print(getmetatable(t)) --nil  
  3. print(getmetatable(12)) --nil  
  4. print(getmetatable("hi")) --table: 0042EB20  
  5.   
  6. t1={}  
  7. setmetatable(t, t1)  
  8. print(getmetatable(t)) --table: 0063B378  

 

13.1算術類元表 

 

假設使用加號(+)來計算兩個集合的并集,,那么需要讓所有用于表示集合的table共享一個元表,并且在該元表中定義如何執(zhí)行一個加法操作,。

算術類元方法字段:__add __mul __ sub __div __unm __mod __pow (__concat)

  1. tA = {1, 3}  
  2. tB = {5, 7}  
  3. mt = {}  
  4. setmetatable(tA, mt)  
  5.    
  6. function union(t1, t2)  
  7.  for _, item in ipairs(t2) do  
  8.    table.insert(t1, item)  
  9.  end  
  10.  return t1  
  11. end  

  1. mt.__add = union  
  2. tAB = tA + tB  
  3. for k, v in pairs(tAB) do  
  4.     print(v)    --1 3 5 7  
  5. end  


 

13.2 關系類的元方法

字段:__eq(==),、 __lt(<)、 __le(<=),,其他Lua自動轉(zhuǎn)換 a~=b --> not(a == b)  a > b --> b < a    a >= b --> b <= a

例如:比較集合大小 <

  1. tA, tB = {3}, {1, 2}  
  2. mt = {}  
  3. function lessthan(tA, tB)  
  4.     return #tA < #tB  
  5. end  
  6.   
  7. mt.__lt=lessthan  
  8.   
  9. setmetatable(tA, mt)  
  10. setmetatable(tB, mt)  
  11.   
  12. print(tA < tB)   --true  


 

與算術類的元方法不同的是,,關系類的元方法不能應用于混合的類型。對于混合類型而言,,關系類元方法的行為就模擬這些操作在Lua中普通的行為,。如果試圖將一個字符串與一個數(shù)字作順序性比較,Lua會引發(fā)一個錯誤,;同樣,,如果試圖比較兩個不同元方法的對象,Lua也會引發(fā)一個錯誤,。

13.3 庫定義的元方法

13.4 table訪問的元方法

算術類和關系類運算符的元方法都為各種錯誤情況定義了行為,,它們不會改變語言的常規(guī)行為。但是Lua還提供了一種可以改變table行為的方法,。有兩種可以改變的table行為:查詢table及修改table中不存在的字段,。

當訪問一個table中不存在的字段時,得到的結(jié)果為nil,。這是對的,,但并非完全正確;實際上,,這些訪問會促使解釋器去查找一個叫__index的元方法,。如果沒有這個元方法,那么訪問結(jié)果如前述的為nil,;否則,,就由這個元方法來提供最終結(jié)果。

__index:  當訪問table中不存在的字段時,,得到的結(jié)果為nil,。

  1. Window = {}  
  2. Window.prototype = {x = 0, y = 0, width = 100, height = 100}  
  3. Window.mt = {}  --Window的元表  
  4.   
  5. function Window.new(o)  
  6.  setmetatable(o, Window.mt)  
  7.  return o  
  8. end  

 

--Window的元方法__index指向一個匿名函數(shù)

--匿名函數(shù)的參數(shù)tablekey取自于table.key,。

  1. Window.mt.__index = function(table,key)   
  2.   return Window.prototype[key]   
  3. end  

 

--下面是測試代碼:

 

  1. w = Window.new{x = 10, y = 20}  
  2. print(w.width)   --100  
  3. print(w.height)   --100  
  4. print(w.width1)  --nil  


 

說明:將一個table作為__index元方法是一種快捷、實現(xiàn)單一繼承的方式,。__index來實現(xiàn)相同功能的開銷比較大,,但方式更加靈活。

__newindex元方法:該元方法用于不存在鍵的賦值,。當對一個table中不存在的索引賦值時,,解釋器就會查找__newindex元方法。如果有這個元方法,,解釋器就調(diào)用它,,而不是執(zhí)行賦值;如果這個元方法是一個table,,解釋器就在此table中執(zhí)行賦值,,而不是對原來的table

具有默認值的table:缺省情況下,,table的字段默認值為nil,。但是我們可以通過元表修改這個默認值

  1. function setDefault(table,default)  
  2.     local mt = {__index = function() return default end }  
  3.     setmetatable(table,mt)  
  4. end  
  5. tab = {x = 10, y = 20}  
  6. print(tab.x,tab.z)  --10    nil  
  7. setDefault(tab,0)  
  8. print(tab.x,tab.z)  --10    0  


 

跟蹤table的訪問:__index__newindex都是在table中沒有所需訪問的index時才發(fā)揮作用的,。因此,,為了監(jiān)控某個table的訪問狀況,我們可以為其提供一個空table作為代理,,之后再將__index__newindex元方法重定向到原來的table,。

 

  1. t = {}        --原來的table  
  2. local _t = t    --保持對原有table的私有訪問。  
  3. t = {}        --創(chuàng)建代理  
  4. --創(chuàng)建元表  
  5. local mt = {  
  6.  __index = function(table,key)  
  7.      print("access to element " .. tostring(key))  
  8.      return _t[key]  --通過訪問原來的表返回字段值  
  9.  end,  
  10.   
  11.  __newindex = function(table,key,value)  
  12.      print("update of element " .. tostring(key) .. " to " .. tostring(value))  
  13.      _t[key] = value  --更新原來的table  
  14.  end  
  15. }  
  16. setmetatable(t,mt)  


 

 

  1. t[2] = "hello"  
  2. print(t[2])  

 

--輸出結(jié)果為

--update of element 2 to hello

--access to element 2

--hello

只讀的table
 通過代理的概念,,可以很容易的實現(xiàn)只讀table,。只需跟蹤所有對table的更新操作,并引發(fā)一個錯誤即可,。

 

第十四章 環(huán)境

環(huán)境:Lua將其所有的全局變量保存在一個常規(guī)的table(環(huán)境)中。

14.1具有動態(tài)名字的全局變量

正因為環(huán)境是一個常規(guī)的table,,才可以使用一個key(變量名)去直接索引它,。類似地,還可以動態(tài)地計算出一個名稱,,然后將一個值賦予具有該名稱的全局變量,。

例如:_G[varname] = name

14.2全局變量聲明

Lua中的全局變量不需要聲明就可以使用。盡管很方便,,但是一旦出現(xiàn)筆誤就會造成難以發(fā)現(xiàn)的錯誤,。我們可以通過_G表加元表的方式來保護全局變量的讀取和設置,這樣就能降低這種筆誤問題的發(fā)生幾率了,。

14.3非全局的環(huán)境:

全局環(huán)境存在一個剛性的問題,,即它的修改將影響到程序的所有部分,。Lua 5為此做了一些改進,新的特征可以支持每個函數(shù)擁有自己獨立的全局環(huán)境,,而由該函數(shù)創(chuàng)建的closure函數(shù)將繼承該函數(shù)的全局變量表,。

 

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多