lua  

Mar 18, 2017 • Michael Chen

雖然 Lua 不是一個主流語言,我們可能會在不經意的情況下接觸到 Lua,像是 Corona SDK、Cocos2d、Gideros Studio、World of Warcraft 外掛等。由於 Lua 的執行環境很小,很容易內嵌在其他軟體中,很多遊戲引擎或其他軟體選擇 Lua 做為腳本語言。由於 Lua 不是一個主流的語言,可能會讓人遲疑是否要使用這些 Lua 相關的軟體。筆者日前以 Corona SDK 開發了一個專案,剛好來談談 Lua 這個語言。

整體來說,Lua 相當易學,這也是當初 Lua 設計的目標之一。有程式設計經驗的 Lua 使用者,可以在幾週內就學完大部分的 Lua 語法,開始將 Lua 用於自己的專案。以筆者為例,筆者非資工、資管背景,有學過幾種程式語言,大約一個月左右,就可以自行用 Lua 撰寫套件及開始用 Corona SDK 製作專案。

Lua 最好的教材是官方出版的 Programming in Lua 和 Lua Reference,購買這些書,還可以順便支持一下 Lua 的發展。另外可以看看 Learn Lua for iOS Games Development,這本書前半部介紹 Lua 語法,後半部介紹 Lua 相關的遊戲引擎和 Lua 生態圈,可做為補充教材。如果沒有要用 Lua 寫物件,僅僅撰寫小型腳本,倒也不一定得買書不可,可以找一些網路上的教程,再自行搭配一些練習題,像是 Exercises for Programmer 等,很快就可以熟悉 Lua。

Lua 現存的版本,大概可分為 5.1 和 5.3 兩個版本,這兩個版本的 Lua 語法和 C API 都有些許差異。由於 Lua 主要用於內嵌在其他軟體中,追著官方最新的版本跑其實沒有必要,有些軟體仍然使用 5.1 版。某些軟體會用 LuaJIT 這套非官方 Lua 實作品,這是因為 LuaJIT 的效能大約是官方版本的 5 至 50 倍之間。LuaJIT 大約相容於 Lua 5.1 至 5.2 版之間。以目前來說,先學 5.1 版反而相容性較佳。

雖然 Lua 有套件的機制,但 Lua 套件數量和 Python 或 Java 等主流語言相差甚遠,根據 LuaRocks 的統計,到 2016 年,LuaRocks 上公開套件僅為 2,000 個左右,相比之下,Python 已有數萬個公開套件。由於 Lua 是內嵌語言,不同軟體各自提供不同的 API,可以把這些軟體視為互不相通的框架。所以,在選擇這些 Lua 相關軟體 (框架) 時,最好先瀏覽一下該軟體的 API 文件和外掛機制,確認該軟體有足夠的特性來支援自己的專案,換框架意味著要重寫一大部分的程式碼,能夠預先避免掉這樣的情形會比較好。

就像其他的高階直譯語言,Lua 雖然好寫,隨著專案規模成長,除錯相對困難。有時候,真正的錯誤不是發生在 Lua 報錯的行數,其實是在更早之前的錯誤引發一連串的異常行為。說實在的,沒有什麼捷徑,還是得耐心地回溯程式碼呼叫的過程,逐步檢查程式狀態的變化,漸進地縮小可疑的程式碼區塊。有時會發現,其實是某個程式碼打錯了,而 Lua 將其視為 nil 傳遞下去而造成難以發現的錯誤。

進階的 Lua 使用者,會將 Lua 和 C/C++ 結合,Lua 的 C API,相對於其他高階語言的 C API 更加容易,這也是 Lua 設計的目標之一。不過,如果讀者只要用現有的框架所提供的 API,不一定會用到這部分的功能,筆者目前也較少使用這方面的特性。

由於 Lua 主要做為內嵌用語言,通常不會是程式設計者的主要工具。不過,Lua 相當容易上手,倒也不需要對這個語言感到害怕。經過一小段時間的學習後,就可以把 Lua 應用在自己的專案。通常我們不會用 Lua 實作全部的程式,而會將需要效能的部分用 C/C++ 撰寫,所幸,Lua 和 C/C++ 橋接不會太困難。

[Update on 2017/06/13]
經過一段時間重新思考後,發現 Lua 其實不是很適合用來建立複雜的專案。因為 Lua 的特性很像 JavaScript,寫起來靈活,但直譯器對程式錯誤的檢查幫助有限,隨著專案規模增加,除錯相對困難。此外,Lua 的套件不若 JavaScript 豐富,且 Lua 內嵌在其他軟體中,使得同一框架的第三方套件更為稀少。Lua 的物件系統相對簡單,在建立較複雜的物件時不若 Java 或 C# 的物件系統來得穩固。但 Lua 做為輔助的命令稿相當方便,仍然可適時發揮其長處。