Lua 程式設計教學:變數和資料型別

變數

變數 (variable) 的作用在儲存值,在後續程式中可呼叫。以下變數 msg 儲存字串 Hello World,再由 print 函式來呼叫:

msg = "Hello World"
print(msg)

函式是預先寫好的程式,需要時由程式撰寫者呼叫即可使用。print 是 Lua 內建的函式,可將變數或值轉為字串印出。

Lua 的變數沒有綁定特定的型別,型別由值本身決定:

var = "Hello World"
assert(type(var) == "string")

var = 12345
assert(type(var) == "number")

在這裡,我們使用兩個內建函式,assert 會斷定函式內的值是否為真,不為真時會中止程式,type 會回傳變數的型別,回傳的值本身為字串。

Lua 比較大的問題在於其變數預設是全域變數 (global variable),而全域變數的有效範圍會超過單一的 Lua 命令稿,當程式規模變大時,這項特性很容易造成程式中難以發現的臭蟲 (bug)。比較好的方式是用 local 宣告局部變數 (local variable):

local msg = "Hello World"
print(msg)

使用 local 宣告的變數,其可視度 (scope) 不會超出該 Lua 命令稿,減少程式出現 bug 的機會。

資料型別

如同大部分的程式語言,Lua 的值具有型別,型別規範可用的操作,像是數字可以加減乘除等。Lua 包括以下八種資料型別:

  • nil
  • 布林 (boolean)
  • 數字 (number)
  • 字串 (string)
  • table
  • 函式 (function)
  • thread
  • userdata

我們將簡要地說明這八種型別。

Nil

Lua 用 nil 表示沒有值,在變數未設置其他值時,該變數的的值即為 nil。將變數設為 nil 即可以刪除此變數。

布林

布林 (boolean) 包括 truefalse,用於邏輯判斷。要注意的是,Lua 的值除了 falsenil 外皆為 true,像是零、空字串、空 table 等皆視為 true,故不能用空值做為 false (偽),這和 C 語言略有不同。

數字

在 5.3 版以前,Lua 的數字皆為倍精度浮點數 (double-precision floating-point),沒有整數 (integer);5.3 版後引入整數型別。在進行數字運算時,若有使用小數點的部位,需注意可能的誤差。在以下程式中,程式會因一些微小的誤差引發錯誤:

-- Error
assert(0.1 + 0.2 - 0.3 == 0.0)

Lua 的數字可用十進位數或十六進位數表示,例如 0xff

字串

Lua 字串是 byte 陣列,沒有限定特別的編碼,甚至可以存二進元數據。從 5.3 版起,Lua 另外有處理 UTF-8 編碼字串的小型函式庫。Lua 對於字串處理能力相對薄弱,也沒有內建的常規表示式 (regular expression) 函式庫。

Lua 是弱型別語言,字串和數字會自動轉換,如下例:

-- Convert numbers to strings.
assert((10 .. 20) == "1020")

-- Convert strings to numbers.
assert(("10" + 1) == 11)

Table

Table 是 Lua 唯一的資料結構,內部為關連式陣列 (associative array)。Table 在 Lua 相當重要,除了用來做為資料結構外,也是 Lua 物件導向程式的基礎。我們將於後續文章討論 table 和物件導向程式。

函式

Lua 的函式除了用來包裝程式碼區塊外,也可做為值使用,也就是說,Lua 可以撰寫函數式程式。我們將於後續文章介紹函式和函數式程式。

Thread

Lua 缺乏真正的多執行緒,而以 coroutine 來代替。

Userdata

Userdata 主要是用來和宿主程式溝通。傳統上,宿主程式是 C 或 C++,不過也可能是其他的程式語言。