亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > 綜合 > 正文

Lua中的函數(function)、可變參數、局部函數、尾遞歸優化等實例講解

2024-07-21 23:04:07
字體:
來源:轉載
供稿:網友

一、函數

在Lua中,函數是作為"第一類值"(First-Class Value),這表示函數可以存儲在變量中,可以通過參數傳遞給其他函數,或者作為函數的返回值(類比C/C++中的函數指針),這種特性使Lua具有極大的靈活性。
 
Lua對函數式編程提供了良好的支持,可以支持嵌套函數。
 
另外,Lua既可以調用Lua編寫的函數,還可以調用C語言編寫的函數(Lua所有的標準庫都是C語言寫的)。
 
定義一個函數

復制代碼 代碼如下:

function hello()
print('hello')
end

 

hello函數不接收參數,調用:hello(),雖然hello不接收參數,但是還可以可以傳入參數:hello(32)
 
另外如果只傳遞一個參數可以簡化成functionname arg的調用形式(注意數值不行)

復制代碼 代碼如下:

> hello '3'
hello
> hello {}
hello
> hello 3
stdin:1: syntax error near '3'

 
另外對變量名也不適用
復制代碼 代碼如下:

> a = 21
> print a
stdin:1: syntax error near 'a'

 
另外,Lua函數不支持參數默認值,可以使用or非常方便的解決(類似Javascript)
復制代碼 代碼如下:

> function f(n)
>> n = n or 0
>> print(n)
>> end
> f()
0
> f(1)
1

 

Lua支持返回多個值,形式上非常類似Python:

復制代碼 代碼如下:

> function f()
>> return 1,2,3
>> end
> a,b,c = f()
> print(a .. b .. c)
123

 
函數調用的返回值可以用于table:
復制代碼 代碼如下:

> t = {f()}
> print(t[1], t[2], t[3])
1        2        3
 
可見,f()返回的三個值分別稱為table的3個元素,但是情況并不總是如此:
復制代碼 代碼如下:

> t = {f(), 4}
> print(t[1], t[2], t[3])
1        4        nil

這次,f()返回的1,2,3只有1稱為table的元素;
復制代碼 代碼如下:

> t = {f(), f()}
> print(t[1], t[2], t[3], t[4], t[5])
1        1        2        3        nil

 
總之:只有最后一項會完整的使用所有返回值(假如是函數調用)。
 
對于無返回值的函數,可以使用(f())的形式強行返回一個值(nil)
復制代碼 代碼如下:

> function g()
>> end
> print(g())
 
> print((g()))
nil

實際上,(f())形式的調用返回一個且只返回一個值
復制代碼 代碼如下:

> print((f()))
1
> print(f())
1        2        3

 

二、變長參數

Lua支持編程參數,使用簡單(借助于table、多重賦值)

復制代碼 代碼如下:

> function f(...)
for k,v in ipairs({...}) do
print(k,v)
end
end
> f(2,3,3)
1        2
2        3
3        3

使用多重賦值的方式
復制代碼 代碼如下:

> function sum3(...)
>> a,b,c = ...
>> a = a or 0
>> b = b or 0
>> c = c or 0
>> return a + b +c
>> end
> =sum3(1,2,3,4)
6
> return sum3(1,2)
3

通常在遍歷變長參數的時候只需要使用{…},然而變長參數可能會包含一些nil;那么就可以用select函數來訪問變長參數了:select('#', …)或者 select(n, …)

 

select('#', …)返回可變參數的長度,select(n,…)用于訪問n到select('#',…)的參數

復制代碼 代碼如下:

> =select('#', 1,2,3)
3
> return select('#', 1,2, nil,3)
4
> =select(3, 1,2, nil,3)
nil        3
> =select(2, 1,2, nil,3)
2        nil        3

注意:Lua5.0中沒有提供…表達式,而是通過一個隱含的局部table變量arg來接收所有的變長參數,arg.n表示參數的個數;

 

三、函數式編程

函數做一個First-Class Value可以賦值給變量,用后者進行調用

復制代碼 代碼如下:

> a = function() print 'hello' end
> a()
hello
> b = a
> b()
hello

匿名函數
復制代碼 代碼如下:

> g = function() return function() print 'hello' end end
> g()()
hello

函數g返回一個匿名函數;
 
閉包是函數式編程的一種重要特性,Lua也支持
復制代碼 代碼如下:

> g = function(a) return function() print('hello'.. a); a = a + 1 end end
> f = g(3)
> f()
hello3
> f()
hello4

 

四、局部函數

局部函數可以理解為在當前作用域有效的函數,可以用local變量來引用一個函數:

復制代碼 代碼如下:

> do
>> local lf = function() print 'hello' end
>> lf()
>> end
hello
> lf()
stdin:1: attempt to call global 'lf' (a nil value)
stack traceback:
stdin:1: in main chunk
[C]: in ?

 

需要注意的是,對于遞歸函數的處理

復制代碼 代碼如下:

> do
local lf = function(n)
if n <= 0 then
return
end
print 'hello'
n = n -1
lf(n)
end
lf(3)
end
hello
stdin:8: attempt to call global 'lf' (a nil value)
stack traceback:
stdin:8: in function 'lf'
stdin:9: in main chunk
[C]: in ?

而應該首先聲明local lf, 在進行賦值
復制代碼 代碼如下:

do
local lf;
lf = function(n)
if n <= 0 then
return
end
print 'hello'
n = n -1
lf(n)
end
lf(3)
end
hello
hello
hello

Lua支持一種local function(…) … end的定義形式:
復制代碼 代碼如下:

> do
local function lf(n)
if n <= 0 then
return
end
print 'hello'
n = n -1
lf(n)
end
lf(3)
end
hello
hello
hello
> lf(3)
stdin:1: attempt to call global 'lf' (a nil value)
stack traceback:
stdin:1: in main chunk
[C]: in ?

 

五、尾調用

所謂尾調用,就是一個函數返回另一個函數的返回值:

復制代碼 代碼如下:

function f()

return g()
end
 
因為調用g()后,f()中不再執行任何代碼,所以不需要保留f()的調用桟信息;Lua做了這樣的優化,稱為"尾調用消除",g()返回后,控制點直接返回到調用f()的地方。
 
這種優化對尾遞歸非常有益,通常遞歸意味著調用桟的不斷增長,甚至可能造成堆棧溢出;而尾遞歸提供了優化條件,編譯器可以優化掉調用桟。
 
下面的遞歸函數沒有使用尾遞歸,而參數為大數時,堆棧溢出:
復制代碼 代碼如下:

> function f(n)
>> if n <= 0 then
>> return 0
>> end
>> a = f(n-1)
>> return n * a
>> end
> f(10000000000)
stdin:5: stack overflow
stack traceback:
stdin:5: in function 'f'
stdin:5: in function 'f'
stdin:5: in function 'f'
stdin:5: in function 'f'
stdin:5: in function 'f'
stdin:5: in function 'f'
stdin:5: in function 'f'
stdin:5: in function 'f'
stdin:5: in function 'f'
stdin:5: in function 'f'
...
stdin:5: in function 'f'
stdin:5: in function 'f'
stdin:5: in function 'f'
stdin:5: in function 'f'
stdin:5: in function 'f'
stdin:5: in function 'f'
stdin:5: in function 'f'
stdin:5: in function 'f'
stdin:5: in function 'f'
stdin:1: in main chunk
[C]: in ?

優化為尾遞歸
復制代碼 代碼如下:

function f(n, now)
if n <= 0 then
return now
end
 
return f(n-1, now*n)
end
f(10000000000, 1)

運行n久也無堆棧溢出;
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产日韩精品电影| 在线精品91av| 色婷婷久久av| 国产日韩精品在线播放| 日韩av免费在线| 久久精品国产91精品亚洲| 91精品国产综合久久久久久蜜臀| 成人免费网站在线看| 国产一区香蕉久久| 精品国产美女在线| 成人黄色av网站| 亚洲电影天堂av| 国产日韩综合一区二区性色av| 中文字幕一区二区精品| 日本成熟性欧美| 91中文在线观看| 九九九久久国产免费| 2020欧美日韩在线视频| 国产精品视频公开费视频| 日韩综合视频在线观看| 精品亚洲一区二区三区在线观看| 97精品国产97久久久久久免费| 日韩在线观看高清| 国产精品永久免费观看| 国产精品久久精品| 欧美性xxxx极品hd满灌| 韩国三级日本三级少妇99| 丝袜亚洲另类欧美重口| 久久天天躁狠狠躁老女人| 日韩精品免费在线视频观看| 国产婷婷97碰碰久久人人蜜臀| 久久久精品国产一区二区| 91高清视频免费观看| 在线看欧美日韩| 国产高清在线不卡| 中文字幕日韩在线观看| 狠狠色噜噜狠狠狠狠97| 欧美日韩国产中文精品字幕自在自线| 国产精品永久在线| 日韩成人在线视频观看| 亚洲人成电影网站色www| 国产精品高清网站| 97视频在线免费观看| 亚洲视频在线播放| 色综合伊人色综合网| 91香蕉亚洲精品| 欧美性生活大片免费观看网址| 久久久在线免费观看| 亚洲精品狠狠操| 国产欧美日韩中文字幕在线| 欧美日韩国产一区在线| 日韩精品视频在线观看免费| 欧美性高潮床叫视频| 国产精品三级久久久久久电影| 97精品一区二区三区| 欧美国产高跟鞋裸体秀xxxhd| 日本久久久久久久久| 亚洲欧美日韩天堂一区二区| 2019最新中文字幕| 欧美精品久久久久久久久久| 国产欧美日韩中文字幕在线| 91免费在线视频| 亚洲精品资源在线| 亚洲国产成人精品久久久国产成人一区| 欧美日韩第一视频| 国产精品青草久久久久福利99| 深夜福利国产精品| 91精品国产91久久久久久最新| 日本道色综合久久影院| 亚洲午夜小视频| 亚洲一区制服诱惑| 欧美大片免费观看在线观看网站推荐| 狠狠色狠狠色综合日日五| 国内免费久久久久久久久久久| 亚洲免费福利视频| 欧美精品www| 成人激情视频在线| 欧美亚洲视频在线观看| 国内伊人久久久久久网站视频| 精品一区二区三区三区| 精品久久久91| 久久91精品国产91久久久| 久久在线视频在线| 精品久久久久久久久久久久久| 性色av一区二区咪爱| 在线看福利67194| 久久影视电视剧免费网站| 毛片精品免费在线观看| 国产欧美日韩精品丝袜高跟鞋| 欧美日韩999| 国产又爽又黄的激情精品视频| 亚洲图片欧洲图片av| 日韩成人黄色av| 亚洲色图综合久久| 97在线精品视频| 一区二区三区国产视频| 国产精品扒开腿做爽爽爽视频| 成人黄色免费网站在线观看| 欧美极品少妇xxxxⅹ裸体艺术| 97成人超碰免| 欧美中文在线字幕| 国产欧美一区二区三区四区| 一本色道久久综合狠狠躁篇的优点| 亚洲黄色www网站| 国产成人一区二区| 97色在线视频| 91久久久久久久一区二区| 在线性视频日韩欧美| 97久久精品视频| 国产精品高潮呻吟久久av黑人| 亚洲人线精品午夜| 欧美精品免费看| 国产精品免费观看在线| 精品久久久久久中文字幕一区奶水| 96精品久久久久中文字幕| 欧美不卡视频一区发布| 影音先锋欧美精品| 国内偷自视频区视频综合| 亚洲女在线观看| 成人免费大片黄在线播放| 欧美在线精品免播放器视频| 精品毛片三在线观看| 欧美野外wwwxxx| 福利视频第一区| 精品在线欧美视频| 日韩中文字在线| 亚洲色图五月天| 一区二区三区回区在观看免费视频| 欧美激情a∨在线视频播放| 色综合久久中文字幕综合网小说| 久久精品国产欧美激情| 欧美一二三视频| 亚洲国产成人91精品| 亚洲第一综合天堂另类专| 色综合久久久888| 亚洲成人黄色网址| 欧美性jizz18性欧美| 亚洲视频在线播放| 中文字幕亚洲色图| 亚洲精品乱码久久久久久按摩观| 亚洲欧美国产精品| 91系列在线观看| 精品中文字幕视频| 亚洲国产91色在线| 国产精品久久婷婷六月丁香| 欧美最猛性xxxxx免费| 亚洲日韩中文字幕在线播放| 国产激情综合五月久久| 日韩中文字幕在线精品| 亚洲自拍偷拍第一页| 亚洲直播在线一区| 亚洲欧洲日产国产网站| 久久国产精品久久久| 欧美成人一区二区三区电影| 久久99精品视频一区97| 在线观看国产精品淫| 91视频国产高清| 亚洲乱码国产乱码精品精天堂| 久久久成人精品视频| 欧美xxxx18性欧美| 色偷偷综合社区| 中文字幕欧美国内| 岛国视频午夜一区免费在线观看| 欧美电影在线免费观看网站|