Lua的閉包詳解(終於搞懂了)


 

詞法定界:當一個函數內嵌套另一個函數的時候,內函數可以訪問外部函數的局部變量,這種特征叫做詞法定界

    table.sort(names,functin (n1,n2)
        return grades[n1]>grades[n2]
    end)
    //內部匿名函數可以訪問外部函數的n1,n2

第一類值:lua當中函數是一個值,他可以存在變量中,可以作為函數參數,可以作為返回值

    function test()
        local i=0
        return function()
            i++
            ...
        end
    end
    //函數作為返回值,這里的i也叫外部局部變量,就是lua中的upvalue

 

閉包:通過調用含有一個內部函數加上該外部函數持有的外部局部變量(upvalue)的外部函數(就是工廠)產生的一個實例函數

閉包組成:外部函數+外部函數創建的upvalue+內部函數(閉包函數)

實例:

    function test()
        local i=0
        return function()//尾調用
            i+=1
            return i
        end
    end
    c1=test()
    c2=test()//c1,c2是建立在同一個函數,同一個局部變量的不同實例上面的兩個不同的閉包
            //閉包中的upvalue各自獨立,調用一次test()就會產生一個新的閉包
    print(c1()) -->1
    print(c1()) -->2//重復調用時每一個調用都會記住上一次調用后的值,就是說i=1了已經
    print(c2())    -->1//閉包不同所以upvalue不同    
    print(c2()) -->2

 

閉包在迭代器中的運用:迭代器需要保留上一次調用的狀態和下一次成功調用的狀態,剛好可以使用閉包的機制來實現

創建迭代器:(一定要注意迭代器只是一個生成器,他自己本身不帶循環)

     function list_iter(t)
            local i=0
            local n=table.getn(t)
            return function()
                i=i+1
                if i<=n then return t[i] end
            end
        end
    //這里的list_iter是一個工廠,每次調用都會產生一個新的閉包該閉包內部包括了upvalue(t,i,n)
    //因此每調用一次該函數產生的閉包那么該閉包就會根據記錄上一次的狀態,以及返回list的下一個

使用迭代器:

        while中使用:
            t={10,20,90}
            iter=list_iter(t)//調用迭代器產生一個閉包
            while true do
                local element=iter()
                if element==nil then break end
                print(element)
                end
            end
        泛型for使用:
            t={10,0,29}
            for element in list_iter(t) do//這里的list_iter()工廠函數只會被調用一次產生一個閉包函數,后面的每一次迭代都是用該閉包函數,而不是工廠函數
                print(element)
            end

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM