【Lua 筆記】簡介 / 基本語法及資料型態 / 變數 - part 1 === 目錄(Table of Contents): [TOC] --- 由於有款遊戲叫做 CSO(Counter-Strike Online),內建模式創世者模式(Studio)新增使用 Lua 及其遊戲的 API,所以突發奇想製作這個筆記。 這個筆記會在一開始先著重純粹的程式設計自學,在最後的章節才會與 CSO 遊戲 API 進行應用。 ## 簡介(Introduction) > Lua(葡萄牙語「月亮」)是一個簡潔、輕量、可擴充的手稿語言。Lua有著相對簡單的C語言API而很容易嵌入應用中。很多應用程式使用Lua作為自己的嵌入式手稿語言,以此來實現可組態性、可擴充性。 - [Wekipedia](https://zh.wikipedia.org/zh-tw/Lua) Lua 建立日期:1993年。by 羅伯托·耶魯薩林斯希、Luiz Henrique de Figueiredo、Waldemar Celes 特性: > Lua 是一種輕量語言,它的官方版本只包括一個精簡的核心和最基本的函式庫。這使得Lua體積小、啟動速度快。它用 ANSI C 語言編寫,並以原始碼形式開放,編譯後的完整參考直譯器只有大約247kB,到5.4.3版本,該體積變成 283kB(Linux,amd64),依然非常小巧,可以很方便的嵌入別的程式裡。 - [Wekipedia](https://zh.wikipedia.org/zh-tw/Lua) 所以 Lua 又可被稱為內嵌語言。 而 Lua 不像是其他種大型語言(如:Python、C、C++ 等),是屬於輕量語言,所以內建的函式庫、資料型態甚少,這也成了他的缺點之一。 :::info 但是學習 Lua 最大的優點是:它,非常好學,因為東西少。 ::: ### 編輯器(Editor) 線上編輯器: * repl.it * glot.io 軟體編輯器: * ZeroBrane Studio * Visual Studio Code 的 extension:vscode-lua * Atom * Notepad++ -> 筆者推薦(因為筆者常用此編輯器) * Decoda 本筆記日後一律使用線上編輯器(repl.it),若等到 CSO 應用部分,則會使用 Notepad++ 軟體作為編輯器。 ## Lua 基本語法 只要是任何剛學一門程式語言的人,一定都會接觸的指令:print("Hello World!") 我們打在編輯器上的時候會長這樣: ![image](https://hackmd.io/_uploads/S1QL3p5rR.png) 然後按下 Run: ![image](https://hackmd.io/_uploads/HJNvn69HR.png) 可以在 Console 旁邊看到 Shell,這個 Shell 其實就跟我們平常開 Windows 的 cmd 命令提示字元是一樣的東西,一次就只能執行一行指令,最主要我們用它還是用於基本的測試用而已。 Console 則就是 print() 後輸出的平台、終端。 輸入、輸出在程式設計上是很重要的概念,print() 的小括號裡面其實就是一種輸入的模式,像我們輸入 "Hello World!",執行後會在終端(Console)上看到 Hello World!。 這時候你肯定會想說:「咦!?為什麼雙引號 "" 沒有被印出來呢?」 沒關係,我們試著把雙引號拿掉看看: ![image](https://hackmd.io/_uploads/S16DTpcr0.png) 出現了這樣子的錯誤。 為什麼?你肯定會產生這個疑惑,因為 Hello World! 本身他是「一串」文字,在程式語言當中,這一串文字稱為字串,需要用 "" 特別去表示文字的意義,否則執行程式時,程式語言不知道 Hello World! 是什麼。 而字串(String),又被稱為是一種資料型態,資料型態(Data Type)又是什麼呢?請待我們下一節解釋。 ## Lua 資料型態(Data Type) Lua 它是一個動態類型的語言,變數宣告時不需要特別去為資料型態定義,只需要為變數指定值即可。這點與大家耳熟能詳的程式語言,Python 是一樣的。 重點來了,資料型態是個什麼東西呢?簡單來說它是用來表示資料的類型的,像是我們在數學中學過實數系,實數可分為有理數、無理數,有理數又可分為整數跟分數,以此類推,資料型態就像是這類的東西, :::info 換句話說,***資料型態就是將資料給分類。*** ::: ![image](https://hackmd.io/_uploads/Hy7RR6qrC.png) 圖源:https://herosnotebook.pixnet.net/blog/post/221459486 在 Lua 中,資料型態可以被分為以下這八種:nil、boolean、number、string、userdata、function、thread、table。 | 資料型態 | 敘述 | | -------- | -------- | | nil | 表示一個無效值(在條件運算式中相當於false)。 | | boolean | true、false。 | | number | 表示雙精度類型的實浮點數。 | | string | 字串由一對雙引號或單引號來表示。 | | function | 由 C 或 Lua 編寫的函數。 | | userdata | 表示任意儲存在變數中的 C 資料結構。 | | thread | 表示執行的獨立線路,用於執行協同程序。 | | table | Lua 中的表(table)其實是一個"關聯陣列"(associative arrays),陣列的索引可以是數字、字串或表格類型。在 Lua 裡,table 的創建是透過"構造運算式"來完成,最簡單構造運算式是{},用來建立一個空表。 | 表格來源:[Lua 数据类型 | 菜鸟教程](https://www.runoob.com/lua/lua-data-types.html) 在這邊老實講,筆者看到第一眼感到驚訝的是,function 竟然會是資料型態耶。 不過這並不是重點,以上這八個資料型態其實不用特地去記,至於他們分別代表什麼,請先看以下範例做練習(範例來源:[Lua 数据类型 | 菜鸟教程](https://www.runoob.com/lua/lua-data-types.html)): 備註:Lua 語言的 -- 符號代表註解,也就是程式不會執行的地方。 ```lua= print(type("Hello world")) --> string print(type(10.4 * 3)) --> number print(type(print)) --> function print(type(type)) --> function print(type(true)) --> boolean print(type(nil)) --> nil ``` 首先第一個我們之前說過,有雙引號 "",然後裡面放東西的形式稱為字串,不過雙引號並不是絕對的,也可以使用單引號,必須注意的是,單、雙引號必須成對,不能一個單引號,一個雙引號。 第二個是 number 的部分,其實原本 number 應該要分為 float、int 的,只不過在 Lua 這邊將它合起來了,浮點數(float:有小數點的)、整數(int)都被稱為是 number 這種資料型態。不過 Lua 他會自動判別哪個是整數,哪一個是小數。 第三個是 function 的部分,像剛剛說 print() 這個指令,它本身是一種函數,用於輸出資料顯示在終端上。 :::info 函數其實就是一種典型的輸入、輸出,就好比把函數想成是一台機器一樣 ::: ,我們在自動販賣機面前輸入錢幣,然後可以盡情的挑飲料(挑飲料就好比是函數的功能),挑完飲料後函數會在下方輸出飲料給我們。 不過話說回來了,type 是什麼東西?type 其實也是一個函數,它主要功能是用來檢測資料型態的類型,比如說 type(1) 回傳的值就會是 number。 ok,資料型態的部分我們先打住,大致上我們只需理解 number、string、nil、boolean、function 是什麼就可以了,讓我們進入下一節變數的部分: ## 變數(variable) 變數是什麼?變數你可以把它想像成,我們之前在學自然科(無論物理化學生物地科)的時候,是否聽過在實驗上被稱作為什麼什麼變因的?像是操作變因、控制變因、應變變因,實際上變數就等於變因。 還是不理解?ok,更淺顯易懂的說明一下,變數它就是一個用來裝水的容器,資料型態就是變數這個容器的形狀,資料型態的值(像是 number 中的 123)就是變數這個容器裡面裝的水。 我們要創建一個變數,得說 "宣告" 一個變數,如下: ``` a = 1 ``` a 等於 1 的說法在程式語言上是錯的,我們通常會說 1 指定給 a、1 指派給 a、1 賦值給 a 等等。 a 可以被賦予任何的資料型態,如下: ```lua= a = 0 a = "ABC" a = true print(a) ``` 輸出結果: ``` true ``` 記得,執行程式時,是由上往下執行的。 ### 多變數指定 Lua 本身也支援多變數指定: ```lua= a, b, c = 0, 1 print(a, b, c) a, b = a + 1, b + 1, b + 2 print(a, b) ``` 輸出結果: ``` 0 1 nil 1 2 ``` 如果有學過其他程式語言的話,像是 Python,絕對不可能會這樣寫,因為會發生未指定變數值的錯誤。不過特別的是,上面程式碼中,第三個 c 沒有特別指定值,所以資料型態就是 nil,等同於空。 然後我們可以透過多變數指定為變數交換值: ```lua= a, b = 1, 2 -- 交換前 print(a, b) a, b = b, a -- 交換後 print(a, b) ``` 備註:`--` 是 Lua 的註解,註解後方可以打上任何的字上去。 ### 識別字(identifier) 識別字(identifier),是用來辨識變數、函數的一個規則,也可以把他想像成是各個名稱的命名規則。 一個識別字從英文字母 A-Z or a-z 或 底線 _ 起頭,需要特別注意的是,就只能用「英文字母」、底線 _ 開頭,其他以外的都不行。以上述開頭之後,就可以放入像是數字(0-9)、底線 _ 等等的其他東西都行,但必須注意的是,無論在什麼位置,都不能以特殊字元為識別字,像是 !@#$%^* 這些等等。 而另外一個需要注意的就是,大小寫不同的識別字是不同的識別字。 以變數名稱為例: ```lua= a = 0 A = 1 print(a, A) -- 0 1 ``` 關鍵字也不能用作識別字: ![image](https://hackmd.io/_uploads/S1V2uR5BC.png) 表格來源:[Lua 基本语法 | 菜鸟教程](https://www.runoob.com/lua/lua-basic-syntax.html) ## 總結 print() - 印出某個東西在終端上顯示 資料型態就是給資料分類,像是 "Hello World!" 這種以文字形式搭配雙引號表示的資料型態稱為字串。 變數就像是裝水的容器(變數的值是水),資料型態作為變數這個容器的形狀。而值(value),就是資料型態的大小,比如說 number:1、45915、0.354135 等,代表 number 這個資料型態的值。 多變數指定:a, b = 1, 2 識別字(identifier),是用來辨識變數、函數的一個規則,也可以把他想像成是各個名稱的命名規則。 規則: 名稱開頭只能是底線或英文字母開頭。 名稱不能有中文,只能是英文字母的 a 到 z、數字(0 到 9)、底線的組合。 Lua 是區分大小寫的語言,以變數名稱為例,兩個大小寫不同的變數名稱,是不同變數。 ## 參考資料 - [[Lua] 程式設計教學:建置開發環境 | 開源技術教學](https://opensourcedoc.com/lua-programming/build-development-environment/)[target=_blank] - [Lua 基本语法 | 菜鸟教程](https://www.runoob.com/lua/lua-basic-syntax.html)[target=_blank] - [Lua 数据类型 | 菜鸟教程](https://www.runoob.com/lua/lua-data-types.html)[target=_blank] - [Lua 变量 | 菜鸟教程](https://www.runoob.com/lua/lua-variables.html)[target=_blank]