又翻起了programming in lua這本書了,而且又看到 感謝貢獻之人這段**,今天就對這段**做下分析。**如下:
-- file: 'thanks.lua'
-- desc: to print the list of the contributing guys
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
endend
helpful_guys =
for e in list_iter( helpful_guys ) do
print(e)
end
對於這段**,我們分兩個部分來講,第一部分是閉包,第二部分是正規化for的執行過程.
首先先講閉包,簡單一點說,閉包就是 乙個內部函式,它可以訪問乙個或多個外部函式的外部區域性變數
結構:包含兩個函式,乙個是閉包自己,乙個是工廠(建立閉包的函式)
-- 這裡list_iter函式是建立閉包的工廠
function
list_iter
( t )
local i = 0
local n = table.getn( t )
-- 匿名函式,list_iter函式的返回值
return
function
() -- 變數i、n和t相對於這個匿名函式,是個外部函式(list_iter)的區域性變數
i = i + 1
if i <= n then
return t[i] end
endend
ffunc = list_iter( )
執行list_iter的返回值就是乙個函式, 它儲存了三個值,i=0, n=2, t=
第一次執行ffunc函式, 即
print( ffunc() )
輸出結果為 a
因為 ffunc 它是乙個函式,執行的時候
i=i+1 這時i=0+1=1
t[1] 就是 a
執行完之後,這個ffunc的儲存的 外部的區域性變數i變成了1
同理再執行一下 ffunc時,
輸出的結果為 b
同時,這個ffunc的儲存的 外部的區域性變數i變成了2
這時候再執行一下的時候,結果就是nil, 因為
i=2+1 等於 3
i<=n不成立了(3<=2不成立)
所以接下來執行的時候,結果都是為nil,
但是每執行一次的時候,ffunc這個閉包的區域性變數i就會加1
function
iter_list
( t )
local i = 0
local n = table.getn(t)
return
function
() i = i + 1
print( "i=", i )
if i<= n then
return t[i]
endendend
ffunc = iter_list( )
print( ffunc() )
print( ffunc() )
print( ffunc() )
print( ffunc() )
執行結果:
接下來講一下正規化for的執行過程
其語法如下
for
in do
end
其中
var-list 是乙個或多個以逗號分割的變數名列表
exp-list 是乙個或多個以逗號分割的表示式列表,迭代函式(閉包),狀態常量和控制變數
通常情況下 exp-list 為:迭代工廠的呼叫。 即: iter_list() 其返回值是乙個閉包
其執行過程為:
do
-- _f為迭代函式,_s為狀態常量,_var為控制變數
local
_f, _s, _var = explist
while
true
do-- 迭代函式的引數有兩個
-- 第乙個是狀態常量_s, 這個值是explist返回的第二個引數
-- 第二個是控制常量,第一次的值是explist返回的第三個引數,後面的值是上次執行_f返回的第乙個返回值
local var_1, ... , var_n = _f( _s, _var )
-- 接下來_f的第二個引數,變成上一次執行_f返回的第乙個值
_var = var_1
-- 如果控制變數為nil就結束
if_var == nil then
break
endblock
endend
上面的解釋可能一開始看不懂,沒關係,接下來根據例項來說明一下,這裡用最開始那個感謝的函式來說明:
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
endend
helpful_guys =
-- 這裡 in 後面的結果,我們希望是乙個迭代函式,乙個狀態常量,乙個控制常量
-- 但是這裡是 list_iter( helpful_guys )
-- 也就是說 local _f, _s, _var = list_iter( helpful_guys )的返回值
-- 因為list_iter只有乙個返回值,所以這裡的三個變數分別為
-- _f 為閉包, _s = nil, _var = nil
for e in list_iter( helpful_guys ) do
-- 第一次執行_f的時候,返回值是helpful_guys的第乙個元素;"----參與翻譯----"
-- 根據上面分析for的執行過程,可知,這裡就是一直執行_f函式,直到其返回值為nil就就結束
print(e)
end
上面的
for e in list_iter( helpful_guys ) do
print( e )
end
等價於
_f, _s, _var = list_iter( helpful_guys )
for e in _f, _s, _var do
print( e )
end
執行的_f的過程中,其實是有傳入狀態常量_s,和後續變化的控制變數_var,只是這裡閉包函式沒有引數而已
我們可以修改一下迭代工廠,就可以看到狀態常量_s和控制變數_var
function
list_iter
( t )
local i = 0
local n = table.getn( t )
-- _s為狀態常量,其值是迭代工廠返回的第二個值,這裡就是 "我是狀態常量"
-- _var為控制變數,第一次是迭代工廠返回的第三個值,後續是閉包執行返回的第乙個值
return
function
( _s, _var )
print( "狀態常量:", _s )
print( "控制量:", _var )
i = i + 1
if i <= n then
return t[i] end
end, "我是狀態常量", "我是初始的控制變數"
endfor e in list_iter( ) do
print(e)
end
執行結果:
SWfit學習2 函式和閉包
函式 swift 使用 func 關鍵字宣告函式 func greet name string,day string string greet hello day world 通過元組 tuple 返回多個值 func getprices double,double,double getprices...
Swift學習3 函式和閉包
1,函式的返回值可以是元組 2,函式的引數可以有預設值 3,輸入輸出引數 用 可以進行位址傳遞 4,函式型別 可以模擬函式指標,可以作為引數,也可以作為返回值 func stepforward input int int func stepbackward input int int func ch...
Python 閉包和裝飾器學習
def out func func functools.wraps 可以將原函式物件的指定屬性複製個包裝函式物件 functools.wraps func def inner func func,args,kwargs return func return inner func out func d...