Lua極簡(jiǎn)入門(六)——函數(shù)的參數(shù)

函數(shù)定義完成后,那么函數(shù)的調(diào)用方式,完成的功能,以及返回值都將固定。此時(shí)就剩下調(diào)用了,對(duì)于調(diào)用函數(shù),只需要關(guān)注參數(shù),并按要求設(shè)置參數(shù),并接收返回值,這樣函數(shù)的整個(gè)流程就完成了。

在Lua中,支持可變參數(shù)定義,即在函數(shù)使用過(guò)程中,傳遞的參數(shù)是可以變化的,可不傳、傳遞一個(gè)、兩個(gè)等等。比如需要計(jì)算一組數(shù)字的累加,那么數(shù)字的個(gè)數(shù)是不固定的。通常會(huì)定義一個(gè)函數(shù),接收一個(gè)table,將不固定的數(shù)字存儲(chǔ)到table中,并作為實(shí)參傳入到函數(shù)中,實(shí)現(xiàn)累加需求:

function adds(numbers)
    total = 0
    for i, v in pairs(numbers) do
        total = total + v
    end

    return total
end

函數(shù)定義完成后,在使用之前,先將數(shù)字添加到一個(gè)table中,之后完成調(diào)用

nums = { 1, 2, 3 }
t = adds(nums)
print(t)
-->> 6
nums = { 1, 2, 3, 4 }
t = adds(nums)
print(t)
-->> 10

以上按傳統(tǒng)的方式實(shí)現(xiàn)了不固定數(shù)字的累加函數(shù)定義。對(duì)于Lua,可以使用可變參數(shù)的定義方法,完成不固定數(shù)字累加的方法,這種實(shí)現(xiàn)及調(diào)用時(shí)更加方便,畢竟不用在聲明table并組織參數(shù):

function adds(...)
    total = 0
    for i, v in pairs({ ... }) do
        total = total + v
    end

    return total
end

上面Lua的可變參數(shù)定義,與傳統(tǒng)函數(shù)(參數(shù)為table)定義方式相比,基本上一致,只是將參數(shù)table變更為了...三個(gè)點(diǎn)。雖然函數(shù)定義時(shí),沒(méi)有太大變化,但是在調(diào)用時(shí),將完全不同。

print(adds())
-->> 0
print(adds(1, 2, 3))
-->> 6
print(adds(1, 2, 3, 4))
-->> 10

參數(shù)中的3個(gè)點(diǎn)... 表示該函數(shù)可接受不同數(shù)量的參數(shù)。當(dāng)調(diào)用時(shí),所有的參數(shù)都會(huì)被收集起來(lái),當(dāng)訪問(wèn)可變參數(shù)時(shí),仍然使用3個(gè)點(diǎn)表示,...在使用時(shí),作為一個(gè)表達(dá)式,如上述中的{...},當(dāng)使用{}標(biāo)記可變參數(shù)時(shí),則將其轉(zhuǎn)換為了一個(gè)table。

三個(gè)點(diǎn)...作為表達(dá)式,可以在函數(shù)中直接使用,但在使用時(shí),會(huì)將所有的可變參數(shù)全部返回。

function adds(...)
    local a, b = ...
    print(a, b)
end

adds(1, 2)      -- 讀取可變參數(shù),并賦值給a,b
-->> 1  2
adds(3, 4, 5)   -- 讀取可變參數(shù),并賦值給a,b,5將會(huì)被丟棄
-->> 3  4

在定義函數(shù)過(guò)程中,可變參數(shù)也可以和固定位置的參數(shù)混用,但可變參數(shù)必須在最后位置。

function adds(name, ...)
    if name ~= nil then
        print("name=" .. name)
    end
    print(...)
end

adds()          -- name 和 可變參數(shù)均為nil
adds(1)         -- name=1,可變參數(shù)為nil
-->> name=1
adds(1, 2, 3)   -- name=1,可變參數(shù)為2,3
-->> name=1
-->> 2  3

在前面,已經(jīng)使用可變參數(shù)...作為表達(dá)式,將其值全部返回,并賦給新的變量;也可以將可變參數(shù)轉(zhuǎn)為數(shù)組{...},并遍歷使用可變參數(shù)。Lua在這兩種讀取可變參數(shù)之外,還提供了select函數(shù),用于訪問(wèn)變長(zhǎng)參數(shù)。該函數(shù)的定義方式為select(index,...),即第一個(gè)位置為固定參數(shù),值包含兩種取值:number#,如果傳遞數(shù)值,則表示獲取可變參數(shù)指定位置的參數(shù),如果為#,則返回可變參數(shù)的長(zhǎng)度;第二個(gè)參數(shù)為可變參數(shù)本身,仍使用...表示。

function adds(...)
    for i, v in pairs({ ... }) do
        print(v)
    end
end
adds(1, 2, nil, 4)
-->> 1
-->> 2
-->> 4

上述中,無(wú)法使用table獲取到傳遞的nil。為了解決這個(gè)問(wèn)題,可以使用select以便獲取參數(shù)總長(zhǎng)度,以及指定位置的參數(shù)。

function adds(...)
    local i = select(2, ...)
    print(i)
    local i = select(3, ...)
    print(i)
    local len = select("#", ...)    -- 獲取可變參數(shù)的長(zhǎng)度
    print(len)
end

adds(1, 2, nil, 4)
-->> 2
-->> nil
-->> 4

可變參數(shù),在使用過(guò)程中,當(dāng)作為表達(dá)式時(shí),完全等價(jià)于原始可變參數(shù),因此可變參數(shù),在一些需要記錄日志時(shí),有著非常良好的應(yīng)用場(chǎng)景,比如類似于Spring切面記錄日志的方式,可以使用Lua的可變參數(shù)來(lái)進(jìn)行模擬

function adds(...)
    total = 0
    for i, v in pairs({...}) do
        total = total + v
    end

    return total
end

function log(...)
    print("執(zhí)行累加操作")
    return adds(...)
end

t = log(adds(1, 2, 3, 4))
print(t)
-->> 執(zhí)行累加操作
-->> 10

在Python中,有一種關(guān)鍵詞參數(shù),在調(diào)用時(shí)允許使用關(guān)鍵字對(duì)參數(shù)進(jìn)行限定,并提供必要的檢查手段,對(duì)于程序的擴(kuò)展,有著良好的作用,如下:

def call(name,**kw):
    pass

call("ray", language='java', position='beijing')

在Lua中,并不具備命名參數(shù)的功能,但是可以使用table進(jìn)行模擬實(shí)現(xiàn),并且當(dāng)參數(shù)只有一個(gè)時(shí),Lua允許直接跟table,因此從實(shí)用上可以實(shí)現(xiàn)類似的效果。

function worker(employee)
    -- 必須具備姓名,開(kāi)發(fā)語(yǔ)言,以及工作年限
    if not employee.name or type(employee.name) ~= "string" then
        error("員工必須具備姓名")
    end
    if type(employee.language) ~= "string" then
        error("必須具備開(kāi)發(fā)語(yǔ)言")
    end
    if type(employee.workingYears) ~= "number" then
        error("需要工作年限")
    end
    -- 還有其他屬性,如籍貫省市,月薪等
    print(employee.province)
    print(employee.city)
    print(employee.salary)
end

worker{
    name = "ray",
    language = "java",
    workingYears = 10,
    province = "beiijng",
    city = "beijing"
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Lua 5.1 參考手冊(cè) by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 14,246評(píng)論 0 38
  • 函數(shù)有兩種用途: 完成指定任務(wù),此時(shí)函數(shù)作為調(diào)用語(yǔ)句使用。 計(jì)算并返回值,此時(shí)函數(shù)作為賦值語(yǔ)句的表達(dá)式使用。 調(diào)用...
    JunChow520閱讀 3,871評(píng)論 0 3
  • 注:lua5.0以上版本去除了table.getn方法,可以用#tableName代替 函數(shù)有兩種用途:1.完成指...
    _小圓球_閱讀 692評(píng)論 1 1
  • 天天洗一次頭是平時(shí)保養(yǎng)頭發(fā)必不可少的一個(gè)過(guò)程,置信許多人都不會(huì)覺(jué)得生疏。白晝?nèi)蝿?wù)忙碌,許多人都喜愛(ài)早晨洗頭或挑選晚...
    wuwu35閱讀 678評(píng)論 0 0
  • 人類自誕生以來(lái),從我們呱呱墜地開(kāi)始,沒(méi)有一個(gè)人不希望自已成為優(yōu)秀的人,嬰兒哇哇嗷叫,付出努力,希望吸引媽媽的關(guān)切,...
    北海棠閱讀 647評(píng)論 0 2

友情鏈接更多精彩內(nèi)容