NODEMCU除錯心得5 函式本無名

2021-07-24 18:22:29 字數 4358 閱讀 2189

這部分應該算關於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 接收器輸出端...