之前的項(xiàng)目開(kāi)發(fā)中有聽(tīng)到同事提及過(guò)有一種寫法函數(shù)在調(diào)用時(shí)會(huì)報(bào)錯(cuò),今天在看書(shū)的過(guò)程中又看到了,記錄下來(lái):
local funA = function(n)
if n == 0 then
return 1
else
return n+funA(n-1)
end
end
print(funA(5))
例如上面的代碼,我們想求1+2+3+ ... +n的和,定義了一個(gè)函數(shù)funA,在funA遞歸調(diào)用自己。
我們運(yùn)行是會(huì)發(fā)現(xiàn)報(bào)錯(cuò)。
lua: FunctionTest.lua:5: attempt to call global 'funA' (a nil value)
funA是個(gè)nil值,也就是我們沒(méi)有定義。
這是因?yàn)長(zhǎng)ua我們的局部函數(shù)funA還沒(méi)有定義完,因此我們想要調(diào)用那么就是個(gè)nil,如果這是有個(gè)全局的函數(shù)funA,那么他會(huì)調(diào)用全局的那個(gè)funA。而非我們想要調(diào)用的局部函數(shù)funA,如下:
function funA(n)
print("我是全局的funA")
return 1
end
local funA = function(n)
if n == 0 then
return 1
else
return n+funA(n-1)
end
end
print(funA(5))
輸出:
[[--
我是全局的funA
6
[Finished in 0.0s]
--]]
對(duì)于這個(gè)問(wèn)題我們可以先定義一個(gè)局部變量,然后在定義行數(shù)本身。如下:
function funB(n)
print("我是全局的funB")
return 1
end
local funB
funB = function(n)
if n == 0 then
return 0
else
return n+funB(n-1)
end
end
print(funB(5))
輸出:
[[--
15
[Finished in 0.0s]
--]]
現(xiàn)在函數(shù)funB中調(diào)用的就是局部函數(shù)funB了。即使在函數(shù)定義的時(shí)候,這個(gè)局部變量的值還有完成定義,但之后函數(shù)執(zhí)行的時(shí)候,funB就已經(jīng)有了正確的值了。
其實(shí)通常我們?cè)趯戇^(guò)的過(guò)程中我們是這樣寫的:
function funC(n)
print("我是全局的funC")
return 1
end
local function funC(n)
if n == 0 then
return 0
else
return n+funC(n-1)
end
end
print(funC(5))
輸出:
[[--
15
[Finished in 0.0s]
--]]
這樣寫在Lua內(nèi)部也會(huì)把其展開(kāi)成:
local funC
funC = function() --todo end