這部分應該算關於nodemcu
的第三節,但是我想取個拽一點的名字。
lua中的函式其實都是匿名函式,沒有名稱。匿名函式是乙個值」value」,就像數值和字串一樣。
既然函式名是乙個變數,因此也可以作為另乙個函式的自變數(argument)。
更常見的情況是,將匿名函式作為argument,另乙個函式就是匿名函式的函式,所謂高階函式。
- 以關於lua
裡的**作為例子
c:on("receive",function(sck,pl) uart.write(0,pl) end)
`c`是`nec.sockt`型別,代表客戶端的連線狀態,c:on的自變數argument包括:「recieve」字串和後面的匿名函式。c:on是匿名函式的高階函式
- 再舉乙個高階函式的例子
list =
table.sort( list,function(a,b) return (a>b) end )
for i,v in ipairs(list) do print(v) end
table.sort( list,function(a,b) return (a^2 > b^2) end )
for i,v in ipairs(list) do print(v) end
table.sort是**的排序函式,第乙個自變數是需要排序的**list,第二個自變數是乙個匿名函式,表示排列的規則,具體含義是相鄰元素之間的關係。
第二行是按周list中的元素大小排列,排列規則為,相鄰元素左側大於右側
第四行是按元素的平方大小排序。
如果乙個函式a()的體內包含另乙個函式b()( 函式b()的statements,或者return包含另乙個函式a() ),a稱作b的封閉函式(也有翻譯成外圍函式的,我不喜歡外圍這個詞)enclosing function
- 封閉函式與高階函式的區別是,乙個是函式位於另乙個函式體內,另乙個是函式是另乙個函式的自變數。用**表示就是:
function b(arg) ... a() ... end --enclosing function
function b(a(),arg) ... end -- higher order function
變數有全域性變數(global variable)和本地變數(local variable)之分,作為變數的函式名同樣有gloable function和local function。
我們之前定義的function都屬於global function,函式名是global variable。如果函式名是乙個local variable,就稱作local function
- 本地函式的定義過程如下:
local sortbysquare
sortbysquare = function(list)
table.sort(list,function(a,b)
return(a^2 >b^2)
end)
end
注意,定義本地函式,一定要先定義本地變數,再給本地變數賦值匿名函式。
不能這樣做:
local sortbysquare = function(list)
...
否則sortbysquare()仍是乙個全域性函式
比較簡單,這裡就不詳細介紹了。
這一部分,我們回顧一下函式中常用的for迴圈
- 數字for迴圈
for i=1,10,2 do print(i) end
1為起始值,10為結束值,2為步長
除了lua語言自身提供的迭代函式pairs和ipaires,也可以自己編寫迭代函式。可以採用閉包形式或者無狀態形式編寫,
- 採用閉包構建迭代函式,
下面給出定義和使用方式
function list_iter (list)
local i = 0
local n = table.getn(list)
return function ()
i = i + 1
if i <= n then return list[i] end
endend
list =
for v in list_iter(list) do print(v) end
ipairs()和pairs()就是採用無狀態的迭代函式,ipairs的內部結構如下:
function iter (list, i)
i = i + 1
local v = list[i]
if v then
return i, v
endendfunction ipairs (list) return iter, list, 0 end
這裡,ipairs()的返回值有三個。iter是迭代函式名,list是iter的第乙個變數,0是第二個變數,初始index
next適用於list和table,可以返回下個index或key,也可以單獨在for迴圈中使用,例如:
for k,v in next,list do .... end
最後,再簡單提一下lua中的各種資料結構:
- 陣列,元素為數字變數的list,陣列可以是一維,二維,或者高維。
對於特殊的一維陣列和二維陣列(矩陣),可以採用for迴圈定義,例如
a = {} -- 定義新陣列
for i=1, 10 do a[i] = fun(...) ... end end
mt = {} -- 建立矩陣
for i=1,n do
mt[i] = {} -- 建立新行
for j=1,m do
mt[i][j] = fun(...) ... end
endend
list = nil
list =
list =
list =
local l = list1
while l do
print(l.value)
l = l.next
endfor k,v in pairs(list) do print(k,v) end
佇列可以用list實現,list同樣可以實現棧結構。
佇列的特點是先進先出 (fisrt in first out,fifo),它的操作函式定義和使用如下
list = {}
-- 初始化序列,定義first第乙個元素和last最後乙個元素對應的index
function list.new () return end
function list.pushleft (list, value)
local first = list.first - 1
list.first = first
list[first] = value
endfunction list.popright (list)
local last = list.last
if list.first > last then error("list is empty") end
local value = list[last]
list[last] = nil
list.last = last - 1
return value
endlist = list.new()
list.pushleft (list, 2)
list.pushleft (list, 3)
list.popright (list)
for i,v in pairs(list) do print(i,v) end
序列的元素包括兩部分,一部分是first和last對應的index,伴隨插入和刪除元素操作,值會變化。另乙個部分是序列內的陣列,index和對應得值。
建立棧結構,實現後進先出功能,(last in first off,lifo)需使用list.popleft()函式,插入元素也可以從右側插入,使用list.pushright()函式,可以仿照list.popright()和list.pushleft()編寫,具體**見這裡
這部分就到這裡了。掌握了lua的函式和資料結構,閱讀韌體中的示例**應該不成問題。如果還有問題,以後再補充。
文中的大部分**來自官方教程,根據文章需要作了修改。
下一部分,按照計畫,講一下網路協議。
事務除錯心得
真正的掌握應該是建立在行動的基礎之上的,正所謂光說不做假把式,以下便談談對事務除錯的心得。1 問題背景 uat測試環境出現單元格 1 單元格 2 單元格 3,單元格 1沒資料,單元格 2沒資料,但是單元格 3卻有資料,後台查 邏輯發現有乙個 update 開頭的service 方法呼叫了 get開頭...
Flex 除錯心得小結
原來在flex 除錯的時候 開始的時候在初始化的時候呼叫 terminalpanel.init 方法 可是總是報錯 因為它裡面用到乙個ip.xml 後來才知道是因為 loadip 內部採用了urlrequest 方法非同步載入ip.xml 檔案 所以會報空指標 所以後來改為在loadip 的 裡面的...
485硬體除錯心得
rs 485標準介面是微控制器系統常用的一種序列匯流排之一。採用半雙工通訊方式,它文成ttl電平轉換為rs 485電平的功能。以max485晶元為例,其結構和引腳都非常簡單,內部含有乙個驅動器和接收器。max485的封裝有dip so和umax三種。dip封裝如下 管腳的功能如下 r0 接收器輸出端...