iT邦幫忙

2021 iThome 鐵人賽

DAY 8
0
Software Development

在麥塊的農場裡寫 Lua系列 第 8

Day8 開機學習 Lua - 迴圈控制、迭代函數

上一回我學到的是 Lua 的條件判斷與迴圈控制
今天我來看最後一段未解的程式碼

for sPath in string.gmatch(settings.get("motd.path"), "[^:]+") do
    if fs.exists(sPath) then
        for sLine in io.lines(sPath) do
            table.insert(tMotd, sLine)
        end
    end
end

目前只剩下 settingsfs 不知怎麼來的?
可以確定的是,他們不是 Lua 內建函式庫
一番搜查之下,我在 bios.lua #783 找到這一段

-- Load APIs
local bAPIError = false
local tApis = fs.list("rom/apis")
for _, sFile in ipairs(tApis) do
    if string.sub(sFile, 1, 1) ~= "." then
        local sPath = fs.combine("rom/apis", sFile)
        if not fs.isDir(sPath) then
            if not os.loadAPI(sPath) then
                bAPIError = true
            end
        end
    end
end

顯然的,他是從 rom/apis 取出所有檔案後,逐一載入
因為有包含了 rom/apis/settings.lua
所以可以直接使用 settings 來讀取或設定環境變數

迭代函數 ipairs

ipairs 也是 Lua 基礎函式庫提供的 function,可迭代 table 中每個數值
每次迭代都會回傳 index, value
特別注意 index 是從 1 開始
然後下面這段 for 迴圈的 code style,跟 Golang 根本一樣啊
也就是 Lua function 也可以回傳多個值
不知道誰學誰 XD
這個迴圈只關心每次取得的檔案名稱,所以 index 就直接捨去了

for _, sFile in ipairs(tApis) do
    -- ....
end

事實上,之前介紹的 io.lines, string.gmatch 也都是 Lua 提供的迭代函數之一

比較差異 ipairs, pairs

iparis固定從 key index = 1 開始
然後 index = 2, index = 3 ... 循序找出 table 內的數值,遇到 nil 就停止
pairs 則沒有按照順序,但遇到 nil 不會停止,一定會把 table 內的非 nil 數值都回傳
以下是測試範例

local tt =
{
    [3] = "test3",
    [2] = nil    ,
    [1] = "test1",
    [5] = "test5"
}
for i, v in pairs(tt) do        -- 輸出 "1test1" "5test5" "3test3"
    print( i .. v )
end

for i, v in ipairs(tt) do        -- 輸出 "1test1" 後就停止迴圈,因為 tt[2] 是 nil
    print( i .. v )
end

fs 呢 ....
這 ... 我找不到宣告 fs 的來源 QQ,只好先擱著,等待通靈的瞬間(逃~
但我想 fs 的函數應該都滿直白易懂的
很容易就能猜到用途和用法

補充說明

~= 在 lua 是不等於的意思
所以這一行的目的是要過濾掉隱藏檔

if string.sub(sFile, 1, 1) ~= "." then

os.loadAPI() 則是在 bios.lua #521 由 CC: Tweaked 自定義的函數
雖然 Lua 也有個 os library

今天就挖礦到這裡
下一回,我會來正式的研究 Lua 函數的定義


上一篇
Day7 開機學習 Lua - 條件判斷與迴圈控制
下一篇
Day9 自訂開機執行的程式碼 - 函數宣告與語法糖
系列文
在麥塊的農場裡寫 Lua30

尚未有邦友留言

立即登入留言