主頁 >  其他 > lua學習之函式篇

lua學習之函式篇

2020-09-11 10:26:20 其他

函式

  1. 函式是對陳述句和運算式進行抽象的主要機制

兩種用法

  1. 一是可以完成特定的任務,一句函式呼叫被視為一條陳述句
  2. 二是以只用來計算并回傳特定的結果,視為一句運算式
print("Hello, World")
a = math.sin(3) + math.cos(10)
print(os.date())

  1. 無論哪種用法都需要將所有引數放到一對圓括號中
  2. 但如果引數是字面字串或 table 構造式的話,可以放在括號中,也可以不放
  3. 即使在呼叫函式時沒有引數,也必須有一個 () 空括號,如呼叫 os.date()
print "Hello, World" -- 等價于 print("Hello, World")
print {1, 2, 3} -- 等價于 print({1, 2, 3})

function add(a)
    local sum = 0
    for i, v in ipairs(a) do
       sum = sum + v 
    end
    return sum
end
b = {1, 2, 3}
add(b)
  1. function 是定義函式的關鍵字
  2. add 是函式名
  3. a 是函式的形式引數,是函式定義式引數串列中的引數
  4. add(b) 呼叫這個函式所傳入的引數稱為實際引數
  5. 呼叫函式的實際引數的個數可以與函式定義時的形式引數個數不同
  6. lua 會自動調整實參的數量,以匹配引數表的要求,這和多s重賦值類似
  7. 若實參少于形參,多余的形參被初始化為 nil
  8. 若實參多余形參,多余的實參被拋棄
  9. lua 程式既可以使用 以 lua 撰寫的函式,也可使用 C 語言撰寫的函式
function f(a, b)
    return a or b
end
f(3) -- a = 3, b = nil
f(3, 4) -- a = 3, b = 4
f(3, 4, 5)  -- a = 3, b = 4 ,5 被丟棄了

定義一個全域的計數器

function intCount(n)
    n = n or 1  -- 賦值一個默認值
    count = count + 1
end

面向物件式呼叫函式

  1. o.foo(o, x)
  2. o:foo(x) 等價于 o.foo(o, x)
  3. 冒號運算子使得我們在呼叫 o.foo 時隱含地將 o 作為函式的第一個引數

多重回傳值

  1. lua 允許函式回傳多個結果
  2. 如標準庫中的一些預定義函式
-- 用于在字串中定位一個模式的函式 string.find
print(string.find("Hello Lua users", "Lua")) -- 開始的位置 7, 結束的位置 9
  1. 在 return 后列出需要回傳的所有值即可,用 , 逗號分隔
-- 查找陣列中的最大元素,并回傳這個元素的所在位置
function maximum(a)
    local mi = 1 -- 最大值的索引
    local max = a[mi] -- 最大值
    for i,v  in ipairs(a) do
   		if v > max then
            mi = i
            max = v
        end
    end
    return max, mi
end
maximum(a) -- 沒有任何反應
print(maximum({3, 4, 23, 5, 7})  -- 23 3
print(maximum({3, 4, 23, 5, 7} .. "a") -- 23a
  1. 如果將函式呼叫作為單獨的陳述句執行,lua 會丟棄所有的回傳值
  2. 如果將將函式作為運算式的一部分呼叫,只保留函式的第一個回傳值
  3. 只有當函式是一系列運算式中的最后一個元素(或只有一個元素的時候),才會獲取所有的回傳值

一系列運算式在 Lua 中的 4 中情況

  1. 多重賦值
  2. 函式呼叫時傳入的實參串列
  3. table 構造式
  4. return 陳述句

多重賦值

  1. 在多重賦值中,如果一個函式呼叫是最后(或僅有)的一個運算式,lua 會保留盡可能多的回傳值,用來匹配賦值的變數
  2. 如果一個函式沒有回傳值或沒有回傳足夠多的回傳值,那么 lua 會用 nil 來補充缺失的值
  3. 如果一個函式呼叫不是一系列運算式中的最后一個元素,就只能回傳一個值
  4. 如果一個函式呼叫作為另一個函式呼叫的最后一個(或僅有的)實參的時候,第一個函式的所有回傳值都會作為實參傳遞給另一個函式
function foo0() end
function foo1() return "a" end
function foo2() return "a", "b" end
-- 多重賦值的4種情況
-- 第一種情況
x, y = foo2() -- x = "a" , y = "b"
x = foo2() -- x = "a"
x, y, z = 10, foo2() -- x = 10, y = "a", z = "b"
-- 第二種情況
x, y = foo0() -- x = nil, y = nil
x, y = foo1() -- x = "a", y = nil
x, y, z = foo2() -- x = "a", y = "b", z = nil
-- 第三種情況
x, y = foo2(), 20 -- x = "a", y = 20
x, y = foo0(), 20, 30 -- x = nil, y = 20
-- 第四種情況
print(foo0()) -- 不會列印任何值
print(foo1()) -- a
print(foo2()) -- a, b
print(foo2(), 20) -- a, 1
print(foo2() .. "x") -- ax

table 構造式

  1. table 構造式可以完整地接收一個函式呼叫的所有結果,即不會有任何數量方面的調整
  2. 但這種行為,只有當一個函式呼叫作為最后一個元素時才會發生
  3. 其他位置上的函式呼叫總是只產生一個結果值
function foo0() end
function foo1() return "a" end
function foo2() return "a", "b" end
t = {foo2()} -- t = {"a", "b"}
t = {foo2(), "x"} -- t = {"a", "x"}

return

  1. 將函式呼叫放入一對圓括號 () 中,使其只回傳一個結果
  2. return 陳述句后面的內容不需要 () 圓括號
  3. 如果強行加上則會使一個多回傳值的函式,強制其只回傳一個 return(f())
function foo0() end
function foo1() return "a" end
function foo2() return "a", "b" end
function foo(i)
    if i == 0 then return foo0() 
        elseif i == 1 then return foo1() 
        elseif i == 2 then return foo2() 
	end
end
print(foo(1)) -- a
print(foo(2)) -- a, b
print(foo(0)) -- 無回傳值

-- () 包裹
print((foo(1)) -- a
print((foo(2)) -- a
print((foo(0)) -- nil 不太懂為什么

unpack 函式

  1. 接收一個陣列作為引數
  2. 并從下標 1 開始回傳該陣列的所有元素
  3. 這個預定義函式由 C 語言撰寫
print(unpack{10, 20, 30}) -- 10 20 30
a, b = unpack{10, 20, 30}  -- a = 10, b = 20
  1. 用于泛型呼叫
  2. 泛型呼叫就是可以以任何實參來呼叫任何函式
-- 呼叫任意函式 f, 而所有的引數都在陣列 a 中
-- unpack 將回傳 a 中的所有值,這些值作為 f 的實參
f(unpack(a)) 
f = string.find
a = {"hello", "ll"}
f(unpack(a)) -- 3 4 等效于 string.find("hello", "ll")

用 lua 遞回實作 unpack

function unpack(t, i)
    i = i or 1
    if t[i] then
        return t[i], unpack(t, i + 1)
    end
end

變長引數

  1. lua 中的函式可以接收不同數量的實參
  2. 當這個函式被呼叫時,它的所有引數都會被收集到一起
  3. 這部分收集起來的實參稱為這個函式的「變長引數」
  4. ... 3個點表示該函式接收不同數量的實參
  5. 一個函式要訪問它的變長引數時,需要用 ... 三個點,此時 ... 三個點是作為一個運算式使用的
  6. 運算式 ... 三個點的行為類似一個具有多重回傳值的函式,它回傳的是當前函式的所有變長引數
  7. 具有變長引數的函式也可以擁有任意數量的固定引數
  8. 但固定引數一定要在變長引數之前
  9. 當變長引數中包含 nil ,則需要用 select 訪問變長引數
  10. 呼叫 select 時,必須傳入一個固定引數 selector(選擇開關) 和一系列變長引數
  11. 如果 selector 為數字 n ,那么 select 回傳它的第 n 個可變實參
  12. 否則,select 只能為字串 "#" ,這樣 select 會回傳變長引數的總數,包括 nil
-- 回傳所有引數的和
function add(...)
	local s = 0
    for i, v in ipairs{...} do -- 運算式{...}表示一個由變長引數構成的陣列
       	s = s + v
    end
    return s
end
print(add(3, 4, 5, 100)) -- 115

-- 除錯技巧 ,類似與直接呼叫函式 foo ,但在呼叫 foo 前先呼叫 print 列印其所有的實參
function foo1(...)
    print("calling foo:", ...)
    return foo(...)
end


-- 獲取函式的實參串列
function foo(a, b, c) end
function foo(...)
        local a, b, c = ...
end
-- 格式化文本 string.format ,輸出文本 io.write
-- 固定引數一定要在變長引數之前
function fwrite(fmt, ...)
    return io.write(string.format(fmt, ...))
end
fwrite() -- fmt = nil
fwrite("a") -- fmt = a 
fwrite("%d%d", 4, 5) -- fmt = "%d%d" , 變長引數  = 4, 5

for i = 1, select('#', ...) do
    local arg = select('#', ...)
    <回圈體>
end

具名引數

  1. lua 中的引數傳遞機制是具有 「位置性」的
  2. 就是說在呼叫一個函式時,實參是通過它在引數表中的位置與形參匹配起來的
  3. 第一個實參的值與第一個形參相匹配,依此類推
  4. 定義:通過名稱來指定實參
  5. 可將所有的實參組織到一個 table 中,并將這個 table 作為唯一的實參傳給函式
  6. lua 中特殊的函式呼叫語法,當實參只有一個 table 構造式時,函式呼叫中的圓括號是可有可無的
os.rename  -- 檔案改名,希望達到的效果 os.rename(old = "temp.lua", new = "temp1.lua")
-- lua 不支持注釋的寫法
rename = {old = "temp.lua", new = "temp1.lua"}
function rename (arg)
    return os.rename(arg.old, arg.new)
end

x = Window{x = 0, y = 0, width = 300, height = 200, title = "Lua", background = "blue", border = "true"}

-- Window 函式根據要求檢查必填引數,或為某些函式添加默認值
-- 假設 _Window 是真正用于創建新視窗的函式,要求所有引數以正確次序傳入
function Window(options)
	if type(options.title) ~= "string" then
        error("no title")
    elseif type(options.width) ~= "number" then
        error("no width")
    elseif type(options.height) ~= "height" then
        error("no height")
	end
    _Window(options.title,
    	options.x or 0 -- 默認值
        options.y or 0 -- 默認值
        options.width, options.height,
        options.background or "white" -- 默認值
        options.border -- 默認值為 false(nil)
    )
    

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/5313.html

標籤:其他

上一篇:lua學習之運算式篇

下一篇:lua學習之復習匯總篇

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more