歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Lua基礎 generic for

下面寫一下怎麼給genericfor 寫迭代器。

1. 迭代器和閉包

在Lua中,迭代器用function表示,每次調用該function,都會返回集合中的next元素。

每個迭代器都要在連續的調用之間保存一些state,這樣才能知道進行到哪一步,下一步該從哪開始處理。在Lua中,閉包可以處理這個問題。閉包結構包含兩個function:一個是閉包本身,另一個是factory,用來創建閉包。下面是個簡單的示例:

function values(t)
    local i = 0
    return function () i = i + 1; return t[i] end
end

在上面的例子中,values是factory。每次調用factory,都會創建一個新的閉包(迭代器本身)。該閉包在變量t和i中保存state。每次調用這個迭代器,都會從t中返回next元素的值。返回最後一個元素後,它會返回nil,標志著迭代器結束。

可以將上面的迭代器用在while 中,但是用genericfor 更簡單:

t = {10, 20, 30}


function value(t)
    local i = 0
    return function () i = i + 1; return t[i] end
end


iter = value(t)
while true do
    local element = iter()
    if element == nil then break end
    print(element)
end


t = {1, 2, 3}
for element in value(t) do
    print(element)
end

執行結果如下:

genericfor 為迭代器循環過程在內部保存state,不需要iter變量;每次迭代都調用該迭代器,並在迭代器返回nil時停止循環。

下面是一個復雜點的例子,從當前輸入的文件中遍歷所有的word。遍歷過程中保存兩個值:當前行(變量line),當前位置(pos),string.find 函數從當前行中搜索一個word,用'%w+'匹配,在匹配到word後,將當前位置pos置於該word之後的第一個字符處,並返回該word。否則,迭代器讀入一個新行再重復上面的過程。如果沒有更多的行,返回nil,標志迭代結束。

function allwords ()
    local line = io.read()
    local pos = 1
    print("allwords begin")
    return function ()
        while line do
            local s, e = string.find(line, "%w+", pos)
            if s then
                pos = e + 1
                print("return the word")
                return string.sub(line, s, e)
            else
                print("read next line")
                line = io.read()
                pos = 1
            end
        end
        print("return nil, iter end")
        return nil
    end
end

for word in allwords() do
    print(word)
end

執行結果如下:

注意執行打印出來的一些信息,可以幫助了解腳本的執行過程。

Copyright © Linux教程網 All Rights Reserved