Corona 初探 Lua 語言,玩跨平台
(iOS & Android) 行動裝置開發工具
學習主題
• 社群成立目的簡介
• 自我介紹與哈啦
• 功力複習
• 程式實作(Corona SDK)
• 問題與交流
個人簡介
諸葛魔斌
工作室:諸葛魔斌科技創作室
學歷:高應大---工管系(非資訊科系)
E-Mail:chugermobin@gmail.com
官方網站:http://twcts.com
Facebook:https://goo.gl/volM7Z
粉絲團 :https://goo.gl/LI08wh
社群 :https://goo.gl/kjCsz1
Line (id) :http://goo.gl/ayGW7d
Line@ :http://goo.gl/pQHjWH
Line Bot :http://goo.gl/ljdxfV
Play商店:http://goo.gl/CkVdsd
App Store:http://apple.co/1Qehd64
專長:VB(VBA)、C#、Java(Android)、Swift(iOS)、PHP、Python、Conrona、
Golang、Unity、MySQL、FreeBSD、Server架設、CAD 、 ……
楊政斌
學習程式的歷程
學生時期:打電動,沒有日夜的界限
二專畢業:初次接觸 dBase、Lotus  使用 Clipper 做經銷存、應收付帳系統
工作階段1:接觸 Office,開始使用Excel(Lotus)
工作階段2:品保工作,自學圖表、函數、VBA,做出自動化品管系統
興趣展開:自學VB,製作ERP系統,接觸Linux、FreeBSD,自學架設Server
 諸葛魔斌誕生
大學時期:半自學 Android App(Java)、C#、iOS App(Swift)
工作轉變:成立諸葛魔斌科技創作室,接案學習,救國團電腦資訊講師
實績:
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
Lua 是一個輕量級的程式語言,該語言是由巴西的 Computer Graphics Technology Group
(Tecgraf) 這家公司的員工 Roberto Ierusalimschy, Luiz Henrique de Figueiredo, and
Waldemar Celes 等人所創造的。
在 1977 年到 1992 年之間,巴西對電腦軟硬體進行了嚴格的貿易管制保護措施,很多需要電腦軟
硬體的公司無法買到國外的軟硬體,於是 Tecgraf 這家主攻「電腦繪圖與使用者介面」的公司就只
好自行發展「程式語言與開發工具」,並且提供給客戶使用。
在設計出 Lua 之前,Tecgraf 其實已經創造過 SOL (Simple Object Language) 與 DEL (data-
entry language) 這兩個程式語言,但這兩個語言並沒有甚麼「流程控制」的語法,於是他們吸取
了 SOL 與 DEL 的設計經驗,然後再參考了 「Modula 語言的 控制結構 (if, while, repeat/until)」,
以及 「CLU 語言的 (多重指定、多傳回值) 等特性」,還有 「SNOBOL、AWK 中的字典
(associative arrays) 概念」,最後創造出了一種語法非常簡易的語言,那就是 Lua。
為何叫做 Lua 呢?Lua 一詞是葡萄牙語中「Luna」(月亮)的意思,因為其前身 SOL 語言的葡萄
牙語意義為「太陽」,所以下一個語言就自然叫做「月亮」囉!
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
Lua 的語法非常的簡單,其 BNF 語法寫起來只有一頁,因此可以說是世界上最簡單的語言之一 (雖
然 LISP 的語法比 Lua 更簡單,其 BNF 應該只要兩三行就寫完了,但是寫起來卻很不容易閱讀;
而 Lua 則是容易讀容易寫,但是 BNF 語法就比 LISP 稍長了一些)。
由於這種簡易的特性,後來 Lua 被廣泛使用在各種遊戲引擎裏做為「腳本語言」(Script Language)
使用,列表如下:
2D 遊戲引擎 : Corona SDK、Love2D、Agen、Blitwizard、Cocos2d-x、EGSL、Grail、MOAI。
2.5D 遊戲引擎 : Lavgine。
3D 遊戲引擎 : Baja、Glint 3d、Irrlicht、Leadwerks、Spring RTS、Luxinia、Polycode、
Cryengine。
另外、Lua 也常被各式各樣需要腳本語言的工具軟體使用,像是 Damn Small Linux、Wikipedia
template engine、Wireshark、Nginx、LuaTeX、Adobe Photoshop Lightroom 等軟體裏都有
內嵌 Lua 腳本語言。
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
Lua 語言特色摘要如下 :
Lua 是動態語言 (Dynamic) :
亦即它是在執行時期 (Runtime) 才做型別檢查, 所以宣告變數時不需要宣告其資料型別, 而且執行中
可任意變換其型別. 其他知名的語言如 Javascript, PHP, Python, Ruby 等都是動態語言. 而 Java
與 C 等靜態語言則是在編譯時期就做型別檢查, 宣告變數時必須同時指定其資料型別, 而且宣告後不
能再更換為其他型別, 若賦予之資料與宣告型別不符就會產生編譯錯誤.
Lua 是弱型別語言 (Weak typing) :
弱型別語言允許一個變數在相對應的記憶體區域中可以存放不同類型的資料, 而強型別語言則不可
以. 弱型別語言的型別推斷功能可以進行較大程度的隱性 (自動) 型別轉換, 反之, 強型別語言的自動
型別轉換則較少, 強弱是相對的, 並非絕對. 注意, 動態語言不一定是弱型別語言, 例如動態語言的
Python 與 Ruby 就屬於強型別語言; 而靜態語言的 Java 也有自動型別轉換, 但是屬於強型別語言.
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
Lua 語言特色摘要如下 :
Lua 擴展能力強 (Extensible) :
Lua 的核心非常精簡小巧, 語法簡潔優美, 類似簡化的英文, 其強大的功能來自於易擴展性, 主要是透
過以 Lua 本身內建或用 C/C++ 編寫的外部函式庫來達成, 也具有 Java, Fortran, Smalltalk, Ada 的
API 介面來擴展函式庫.
Lua 可嵌入其他語言中 (Embedable) :
Lua 可以嵌入到 C/C++, Java, C#, Python, Ruby, Perl 等其他語言中, 做為其函式庫使用. 而且
Lua 可以雙向呼叫 (bi-directional), 亦即可由 Lua 呼叫宿主語言函式, 也可以由宿主語言呼叫 Lua
函式, 一般腳本語言通常只專注在呼叫外部函式庫.
Lua 是跨平台語言 (Portable) :
Lua 以 ANSI C/C++ 語言編寫而成, 可在多數作業系統上執行, 甚至在嵌入式系統如手機 Android
與 iPhone, 遊戲機 PSP, PS3, 甚至以 WiFi 晶片 ESP8266 為基礎的 NodeMCU 上也可以執行, 可
移植性極高.
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
Lua 的優勢是執行速度快, 語法簡單學習曲線不陡峭
(參考 http://yhhuang1966.blogspot.tw/2015/07/lua_14.html)
(參考 http://coronaintaiwan.blogspot.tw/2013/04/blog-post.html)
區塊 (chunk 或 block) :
Lua 程式的一段陳述 (statement) 稱為 chunk, 它可以是指一條指令, 也可以是一群指令. 例如 :
a=100
print(a)
或者
a=100 print(a)
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
Lua 的優勢是執行速度快, 語法簡單學習曲線不陡峭
區塊 (chunk 或 block) :
每條指令間不須像 Javascript 或 PHP 那樣用分號結尾, 直接跳行即可, 但用分號結尾也是可以的
(行尾的分號對 Lua 而言是可有可無的, optional), 例如 :
a=100;
print(a);
但如果兩條敘述要寫在同一行就必須用分號隔開 (不是用逗號), 例如 :
a=100; print(a)
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
Lua 的優勢是執行速度快, 語法簡單學習曲線不陡峭
區塊 (chunk 或 block) :
最常見的區塊是函數 (function end), 迴圈 (for end, while end, repeat end), 判斷 (if end), 以及匿
名區塊 (do end), 在這四種區塊內的變數都是自成一個單元, 享有相同的作用域或環境 (scope,
context) :
function function1()
--do something
end
for a=1, 100, 5 do
--do something
end
if a<=10 do
--do something
end
do
--do something
end
注意, 在 Lua 解譯器的交談模式中, 每一行完
整的指令就是一個 chunk, 所以這一行定義的
區域變數跳到下一行時是新的一個 chunk, 已
經超出其作用域 (scope) 而無法存取, 執行的
結果將不受上一行區域變數之影響. 此問題可
用 do end 區塊解決, 包含在此區塊內的陳述
都屬於同一 chunk.
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
程式註解 :
Lua 使用開頭的兩個 dash (--) 作為單行註解符號 (一直到行尾), 例如 :
--這是單行註解行
多行註解則是使用兩個 dash 與雙中括號 --[[ 開頭, 一直到下一個雙中括號為止, 所包含的區域解譯
器會略過不予處理 :
--[[這是
多行
註解]]
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
程式註解 :
例如下列範例 test.lua :
--[[
print ("Hello World!")
]]
print ("Hello World!")
執行此程式只會印出一行 "Hello World!", 因為第一個 print 指令被註解掉了不會執行.
在程式開發過程中, 為了除錯方便常會使用多行註解來控制某一段程式是否要執行, 測試完畢後又要
把 --[[ 與 ]] 分別去掉, 有個取巧的辦法可以解決此麻煩, 就是在結尾中括號前也加上雙 dash :
--[[
print ("Hello World!")
--]]
print ("Hello World!")
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
程式註解 :
這樣當要取消註解, 讓原先被註解掉的程式碼恢復執行時, 只要在註解開頭處再加一個 dash 即可
(因為 ---[[ 中前面的兩個 dash 把這行變成單行註解, 迫使結尾的 --] 單飛為單行註解, 多行註解破
功) :
---[[
print ("Hello World!")
--]]
print ("Hello World!")
這樣註解頭失去多行註解功能, 而註解尾變成單行註解, 不用刻意去除. 這個程式會印出兩行 "Hello
World!".
但中括號有時令人覺得眼花撩亂, 一律使用 -- 其實會比較整齊與單純.
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
識別字 (Identifier) 與保留字 :
識別字用來指派變數或函式名稱, Lua 識別字的限制與 Javascript 一樣, 只能使用英文字母, 數字,
以及底線之組合, 但是第一個字元不可以是數字, 所以 2au 不是合法的識別字. 此外雖然可以用底線
開頭, 但是因為 Lua 解譯器內部使用以底線開頭的變數, 特別是用底線開頭, 後面是大寫字母組成的
識別字, 例如 _VERSION (這是 Lua 特殊用途的保留字), 所以最好不要用底線開頭來命名變數, 以免
與系統衝突.
另外, Lua 有 22 個保留字, 這些都不能拿來當識別字 :
local nil not
or and
if then else elseif
for end in do while until repeat break
true false
function return
goto
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
識別字 (Identifier) 與保留字 :
其中 nil 即 Javascript 或 PHP 的 null 或 NULL, 即無值之意. 被設為 nil 的變數會在記憶體管理下
一次掃描時被垃圾回收而消失. 相較於 Javascript 有 29 個保留字, Python 的 33 個, Java 的 50
個, PHP 的 53 個, 而 C# 高達 87 個, Lua 卻只有 22 個, 可見 Lua 有多精簡.
Lua 是有分大小寫的 (case-sensitive), 所以 and 是保留字不能用, 但 AND, And 卻是合法的識別字.
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
全域變數與區域變數 :
只要不是用 local 宣告的變數都是全域變數, 即使它位於函數或迴圈等區塊中, 例如 :
a=100
全域變數一經賦值後就會一直存在記憶體中, 直到被設為 nil 才會被記憶體管理回收. 存取未賦值的
全域變數會得到 nil. 全域變數實際上會放在名為 _G 的特殊表格中 (Table, 即關聯式陣列, 是 Lua 唯
一的資料結構, 所有的變數, 函式都是以 table 來儲存), 安全性較高.
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
全域變數與區域變數 :
區域變數是以 local 宣告的變數, 其作用域 (scope) 僅限於所在之區塊 (block) 內, 例如在函式, 分岐控
制, 迴圈或 do end 結構中使用的變數應該宣告用 local 宣告為區域變數. 區塊中的區域變數會掩蓋同
名的全域變數 (即不會存取到同名之全域變數), 意即更改區域變數之值不會影響全域變數的值. 當程式
區塊執行結束時, 區塊內的區域變數就會被記憶體管理自動回收 (因此不需要刻意在區塊末尾將其設為
nil). 唯一的例外是, 如果全域變數有參考到區域變數, 則此區域變數不會隨著區塊結束而被回收, 例如 :
a=1
function myfunc()
local b=2
a=b --全域變數 a 參考到區域變數 b
end
myfunc()
print(b) --輸出 nil (無法存取到區域變數)
print(a) --輸出 2
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
全域變數與區域變數 :
由於全域變數 a 在函數內參照了區域變數 b, 使得 b 被全域化, 因此在呼叫函數 myfunc() 後, 原本是區
域變數的 b 無法正常地被垃圾回收而留存在記憶體中 (但在上層全域卻看不到), 成為垃圾回收的漏網
之魚. 這種參照方式要盡可能避免, 否則可能因 memory leak 造成程式崩潰.
除非必要不要使用全域變數, 要盡量使用區域變數, 因為它的執行速度比較快, 而且在記憶體運用上也
較有效率, 當它到達作用域盡頭時就會失去作用而被記憶體管理自動回收. 因為當 Lua 解譯一個變數時,
如果它前面有 local 標示為區域變數, 則解譯器會在目前的區域中尋找此變數, 找不到就是 nil; 如果沒
有 local, 就會往上一層去找, 直到最上層為止, 找不到才是 nil, 因此全域變數要花較多時間尋找, 會影
響執行效率, 所以除非是必要的全域變數, 盡量使用區域變數. 例如 :
local a=1
local b=2
if a print(a) --> 輸出 1
local a=10 -- then 區塊內的區域變數, 不影響外面的區域變數 a
print(a) --> 輸出 10
end
print(a) --> 輸出 1
print(b) --> 輸出 2
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
多重指派 (multiple assignment) :
Lua 跟 Python 一樣具有多重指派語法, 可以在一個陳述中同時為多個變數賦值, 各變數以逗號隔開,
例如在交談模式中 :
> do
>> local a,b,c=1,2,3
>> print(a,b,c)
>> end
1 2 3
但如果賦值不足, 則未賦值之變數預設為 nil, 例如 :
> do
>> local a,b,c=1,2
>> print(a,b,c)
>> end
1 2 nil
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
多重指派 (multiple assignment) :
若賦值超過變數之數目, 多出來的值會被視而不見略過. 多重指派讓資料交換變得很簡潔, 只需要一條
指令即可 :
local a,b=1,2
a,b=b,a --交換後 a=2, b=1
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
Lua 是動態弱型別語言, 其變數是無型態的 (typeless), 宣告時不需要指定資料型態, 但變數的值當然
有型態, 因為解譯器是靠值的資料型態來動態地配置記憶體.
Lua 有八種資料型態 :
(1). nil (無值)
(2). boolean (布林)
(3). number (數值)
(4). string (字串)
(5). table (表格, 關聯式陣列)
(6). function (函式)
(7). thread (執行緒)
(8). userdata (使用者資料)
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
前面六種都是其他語言中常見的型態, 而 thread 與 userdata 則較特殊. 事實上這八種資料都是使用
table 來實作的, 因為 table 是 Lua 唯一的資料結構. 使用者定義資料 userdata 是記憶體中的一個區塊,
用來給 C 函式透過 API 存取資料, Lua 無法建立或操控此資料. 而 thread 是用來指派一個例外的獨立
執行緒, 但這與一般作業系統的 thread 不同, Lua 不支援真正的多執行緒 (先佔式記憶體分享, 因為
ANSI C 不提供), 不過 Lua 透過 coroutine 提供非先佔式或非記憶體分享多執行緒. 而 thread 就是
coroutine 與低層 API 的組合.
Lua 有一個內建函數 type() 可用來檢測變數的資料類型, 例如 :
print(type(1)) --輸出 number
print(type("Tony")) --輸出 string
t={}
print(type(t)) --輸出 nil (因為是個空的表格)
t={name="tony"}
print(type(t)) --輸出 table
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
以下整理最常用的字串, 數值, 布林值, 與無值 nil.
(1) nil
nil 相當於 Javascript 的 null, 表示一個變數無值, 即尚未初始化. 一個變數只宣告而未賦值, 預設就是
nil. 全域變數一經宣告就會存在於記憶體中, 除非我們把它設為 nil 才會被垃圾收集機制刪除.
(2). boolean
在 Javascript 中 true 與 1, false 與 0 是同義的, 但在 Lua 卻不同, Lua 的布林值只有 true 與 false
兩種, 1/0 並非 true/false 的別名, 配合 not, and 與 or 運算用在條件控制的邏輯判斷上. 但 Lua 的條件
控制並非只能依賴這兩個布林值, boolean 以外的型態都可以用在邏輯判斷, 但除了 false 與 nil 在邏
輯上為假外, 其他均為真, 例如 :
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
b=0.22
if (b) then print("true") --> 印出 true
else print("false")
end
但是要注意, Lua 的 and 與 or 運算結果有點特別, 採用所謂 shortcut evaluation (捷徑估值法), 其傳
回值不一定是 true 或 false, 而是取決於第一個運算元. 如果 and 運算的第一個運算元是 false 或 nil,
就直接傳回第一個運算元 (即 false 或 nil); 否則傳回第二運算元, 例如 :
print(nil and 5) --> 印出 nil (第一個是 nil/false 就傳回 nil/false)
print(false and "OK") --> 印出 false (第一個是 nil/false 就傳回 nil/false)
print(2.2 and "OK") --> 印出 OK (第一個不是 nil/false 就傳回第二個)
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
其次, 如果 or 運算的第一個運算元是 nil 或 false, 就直接傳回第二個運算元, 否則就傳回第一個運算元,
例如 :
print(nil or 5) --> 印出 5 (第一個是 nil/false 就傳回第二個)
print(false or "OK") --> 印出 OK (第一個是 nil/false 就傳回第二個)
print(2.2 or "OK") --> 印出 2.2 (第一個不是 nil/false 就傳回自己)
運算元最好只使用 true, false/nil 來進行運算, 以免邏輯判斷出現非預期結果.
與布林值有關的除了邏輯運算外還有關係運算子 :
> (大於) < (小於) >= (大於等於) <= (小於等於) == (等於) ~= (不等於)
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
與其他語言比較不同的是 Lua 用 ~= 表示不等於 (C/Java/PHP 等使用 !=), 例如 :
if (nil ~= false) then print("不相等") end --> 印出 不相等
if (2.2>0) then print("正數") end --> 印出 正數
注意, 資料型態不同的變數不能使用關係運算子加以比較, 特別是比大小運算子 ( >, <, >=, <=) 會出現
錯誤訊息. 例如 :
> if ("OK">0) then print("正數") end
stdin:1: attempt to compare number with string
stack traceback:
stdin:1: in main chunk
[C]: in ?
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
必須是相同資料型態才能進行含有大小的比較, 例如 :
if ("smart">"rich") then print("smart is better") --> 印出 smart is better
else print("rich is better")
end
而 == 與 ~= 這兩個與大小無關的運算即使資料型態不同也不會出現錯誤, 例如 :
if ("knowledge" == 0) then print("idiot")
else print("expert") end --輸出 "expert"
事實上, == 與 ~= 運算會先去看兩個運算元資料型態是否相同, 然後再去比較其內容. 前者 == 會先看資
料型態是否相同, 如果不同就直接傳回 false (不用比內容啦!), 型態相同才去比較內容, 相同傳回 true,
不同傳回 false, 例如 :
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
if 1==true then --資料類型不同傳回 false
print("same")
else
print("different") --輸出 different
end
if ("power" == "power") then print("power is power")
else print("power is not power") end --輸出 "power is power"
if ("knowledge" == "power") then print("knowledge is power")
else print("knowledge is not power") end --輸出 "knowledge is not power"
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
而 ~= 運算只要型態不同, 就直接傳回 true 了; 若型態相同才去比內容, 相同傳回 false, 不同傳回 true,
例如 :
if ("money" ~= 0) then print("have money")
else print("have no money") end --輸出 "have money"
if ("knowledge" ~= "power") then print("knowledge is not power")
else print("knowledge is power") end --輸出 "knowledge is not power"
對於 table, function 等物件, 變數儲存的是參考 (指向實際的資料儲存位置), == 與 ~= 運算比較的是其
參考, 例如 :
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
t1={1,2,3}
t2={1,2,3}
if t1==t2 then print("same")
else print("different") --輸出 different (t1 與 t2 是不同參考)
end
t3=t1 --複製參考, t3 與 t1 指向同一個 table
if t1==t3 then print("same") --輸出 same
else print("different")
end
上例之 t1 與 t2 雖然內容相同, 但參考不同, 故 t1==t2 運算傳回 false, 而 t3=t1 是複製參考, 兩者指向
同一個 table, 故 t1==t3 傳回 true.
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
(3). number
數值方面, 可以使用 10/16 進位整數, 小數, 科學表示法來表示, 但 Lua 並沒有整數型態, Lua 的數值一
律使用雙準度浮點數儲存 (IEEE 754). 例如 :
print(2000) --> 印出 2000
print(3.14159) --> 印出 3.14159
print(2e3) --> 印出 2000.0
print(2E-2) --> 印出 0.02
雖然使用浮點數來表示整數, 但在 Lua 不會產生進為誤差 (rounding errors).
科學表示法的指數用 e 或 E 都可以. 如果要表示 16 進位數, 數值就要以 0x 或 0X 開頭, 例如 :
print(0xff) --> 印出 255
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
數值的運算子有如下七個 :
+ (加) - (減) * (乘) / (除) % (餘數) ^ (次方) - (單元運算, 負數), 例如 :
print(1/2) --> 印出 0.5
print(5%3) --> 印出 2
print(2^10) --> 印出 1024.0
print(-2) --> 印出 -2
當字串與數字混合運算時, Lua 會進行自動轉型, 將數字字串轉成數字再運算, 例如 :
print(1+"100") --輸出 101.0
print(1+".1") --輸出 1.1
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
(4). string
Lua 的字串與 Java 一樣是不可變的 (immutable), 對字串的操作事實上是產生另外一個新字串. 字串
的用法跟 Javacript 或 PHP 類似, 可用雙引號或單引號括起來, 除此之外, 也可以用兩個中括號對 (主
要用在跨行的長字串), 例如 :
a="Hello"
b='World'
print(a,b) --> 印出 Hello World
print([[Hello World!]]) --> 印出 Hello World!
如果字串中有引號時, 只要秉持成對 (matching) 與替換 (alternate) 原則就不會弄錯, 例如 :
print("This is Tony's book.") --> 印出 This is Tony's book.
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
這裡所有格必須用單引號, 因此整個字串要用雙引號括起來. 如果用單引號就會出錯 :
print('This is Tony's book.') --> 錯誤! stdin:1: ')' expected near 's'
如果堅持用單引號, 則所有格必須用倒斜線跳脫 :
print('This is Tony's book.') --> 印出 This is Tony's book.
或者乾脆用雙重中括號免得麻煩 :
print([[This is Tony's book.]]) --> 印出 This is Tony's book.
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
常用的跳脫字元如下 :
" : 雙引號
' : 單引號
n : 換行
r : 回車
 : 倒斜線
字串也可以用 ASCII 編碼來表示 (如果覺得這樣很有趣, 又不會太麻煩的話), 例如 ABC 的 ASCII 編碼
以十進位表示分別為 65, 66, 67, 所以要印出 "ABC" 可以用倒斜線跳脫 ASCII 碼來表示 :
print("656667") --> 印出 ABC
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
也可以用十六進位表示, 但要加一個小寫 x (不能用大寫 X) :
print("x41x42x43") --> 印出 ABC
參考 : Wiki : ASCII
對於可能會超過一行長字串, 為了編輯的方便需要拆成數行時, Lua 提供兩個方式來輸入長字串, 第一
個是用 [[ 與 ]] 符號來包圍一塊長字串區域, 例如 :
a=[[This is a very
very
very ...
long story.]]
print(a)
印出的結果與編輯時的樣子相同, 會保留所有的空格.
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
第二個方法是用跳脫字元 z 來串接長字串, 例如 :
a="This is a very z
very z
very ... z
long story."
print(a) --> 印出 This is a very very very ... long story.
可見使用 z 不會保留空格, z 會直接串接到下一行的非空白字元.
Lua 取得字串長度是在字串前面加個 "#", 例如 :
print(#"ABC") --> 印出 3
a="Hello World!"
print(#a) --> 印出 12
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
也可以使用內建的 string.len() 函式, 例如 :
print(string.len("Hello World!")) --> 印出 12
至於串接字串, 有別於 Javacript 用加號, PHP 用點號, Lua 是用連續兩個點號來串接字串, 例如 :
print("Hello".." ".."World!") --> 印出 Hello World!
由於 Lua 是弱型態語言, 當數值字串進行數值運算時會自動進行型態轉換, 例如 :
print("12" + 3) --> 印出 15, 會先將 "12" 轉成 12 再加 3.
print("4.5e25" * "3") --> 印出 1.35e+026
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
但如果不是數值字串, 就會無法轉成數值而發生錯誤, 例如 :
> print("1 hundred" + 900) --> 1 hundred 不是數值
stdin:1: attempt to perform arithmetic on a string value
stack traceback:
stdin:1: in main chunk
[C]: in ?
反之, 當數值進行字串運算時, Lua 也會自動將數值先轉成字串再運算, 例如 :
print(20 .. 15) --> 印出 2015
注意, 這裡數值與字串串接運算符 .. 之間必須有一個空格, 否則第一個點會被認為是小數點而產生
malformed number 錯誤.
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
以上是數值與字串的隱性型別轉換, 顯性的轉換則是利用 tonumber() 與 tostring()函式, 例如 :
if (tonumber("2e2") == 200) then print("match") end --> 印出 match
if (tonumber("10.5") == 10.5) then print("match") end --> 印出 match
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
(5). Table (表格)
Lua 的 table 其實就是關聯式陣列 (associative array), 這是 Lua 唯一的資料結構, 所有的資料型態都
是用 table 來實作的, 例如全域變數就是儲存在名為 _G 的特殊表格中, 宣告一個全域變數 a="123" 其
實跟 _G["a"]="123" 是一樣的. 在其他語言中常見的陣列 (array), 串列 (list), 紀錄 (record), 佇列
(queue), 或集合 (set) 等, Lua 都用 table 來實現.
Lua 的 table 是用大括號來宣告的 :
t={} --> 宣告一個空的表格
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
表格是一種關聯式陣列, 所以可以用數字當索引, 也可以用字串當索引, 事實上, 在 Lua 中除了 nil 外,
任何值都可以當 Table 的索引, 例如 :
t={}
t[0]="peter"
t[2]=23
t["2"]=45 -- 這跟 t[2] 無關
t["gender"]="female"
print(t[2]) --輸出 23
print(t[2"]) --輸出 45
print(t["age"]) --輸出 nil (無此元素不會出現錯誤, 而是認為新元素賦值 nil)
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
當然也可以在宣告時同時賦值, 例如 :
t={[0]="peter", [2]=23, ["gender"]="female"} -- 注意喲, 索引必須用中括號
如果索引名稱符合識別字限制 (英數字與底線組合, 不以數字開頭), 則中括號與引號可以省略, 例如 :
t={name="peter", age=23, gender="female", _class=0}
所以, 索引 a 與 ["a"] 是同樣的意思, 下列宣告前後都是同一元素, 後者的會蓋掉前者 :
t={["a"]=123, a=456}
print(t["a"]) --> 印出 456 (被覆蓋了)
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
Table 的最後一個元素若跟著逗號是允許的, 例如 :
t={1,2,3,}
這對於以迴圈自動產生 Table 元素非常方便, 因為不需要花功夫去除最後一個逗號.
雖然都是關聯式陣列, 但 Lua 的 table 跟 PHP 的關聯式陣列在索引的使用上是不一樣的, 以數值當索
引時, PHP 只能用 0 與正整數當索引, 而 table 的索引則不限於整數, 可以是任何數值, 可用實數, 也可
以是布林值, 例如 :
t={}
t[2.2]="too small"
t[2.2e10]="too big"
t[-199.99]="negative"
t[true]=true
t[false]=false
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
對於字串索引, Lua 也提供點符號來存取表格, 這跟物件或紀錄 (record) 的用法是一樣的, 例如 :
t={}
t.name="peter" -- 相當於 t["name"]
t.age=23 -- 相當於 t["age"]
t.gender="female" -- 相當於 t["gender"]
t._ID1="S1122334455" -- 相當於 t["_ID1"]
注意, 這裡點後面的欄位名稱受識別字命名法規範, 亦即只能用英文字母, 底線與數字之組合, 而且不能
用數字開頭, 例如 t.2xy 是不合法的.
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
這種點符號最容易讓人誤解之處是, 點後面的欄位名稱是個字串, t.a 意思是 t["a"], 而不是t[a], t.a 的 a
就是字串 "a", 而 t[a] 的 a 是指一個變數 a, 所以 t[a] 的索引決定於 a 變數的值, 例如 :
t={}
a="x"
t[a]=1 -- 即 t["x"]=1
print(t.a) --> 印出 nil (因為 t.a 就是 t["a"], 並未定義故為 nil)
print(t[a]) --> 印出 1 (因為此 a 為變數, t[a] 即 t["x"], 已設為 1)
如果要用 table 來實作一般的陣列, 而非關聯式陣列, 那就略過索引的指定, 直接把元素的值放在中括號
內即可, 例如 :
t={1, 2, 3}
print(t[0]) --> 印出 nil
print(t[1]) --> 印出 1
print(t[2]) --> 印出 2
print(t[3]) --> 印出 3
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
如果要知道陣列長度 (即有幾個元素), 跟取得字串長度一樣, 使用 # 運算子即可 :
t={"a", "b", "c", 1, 2, 1.7e-34}
print(#t) --> 印出 6
但要注意的是, 存取元素時, 索引是從 1 開始算的, 而不是像 Javascript 或 PHP 那樣是從 0 開始, 因為
在不指定索引的情況下, Lua 的整數索引預設是從 1 開始數的, 這在 Lua 是普遍的法則. 要不, 你就得
自行指定索引 (愛從哪開始就從哪開始) :
t={[0]=1, [1]=2, [2]=3}
print(t[0]) --> 印出 1
print(t[1]) --> 印出 2
print(t[2]) --> 印出 3
print(t[3]) --> 印出 nil (未定義)
但這樣就失去懶人的目的了.
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
Lua 允許使用負數做為陣列索引, 但是 # 運算子卻只能計算索引為 1 起始的整數索引元素, 例如 :
t={}
for i=-5,5 do
t[i]=i
end
print(#t) --輸出 5
表格的元素也是可以是另一個表格, 謂之巢狀表格, 而且可以要多深就有多深, 例如 :
t={name="peter", im={qq="1234567890", skype="aaa"}}
print(t.im.qq) --> 印出 1234567890
print(t["im"]["skype"]) --> 印出 aaa
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
可以用 key 或 index 兩種方式來存取巢狀表格的元素.
表格的元素也可以由函數的傳回值來產生, 例如 :
function odd()
return 2,4,6,8,10 --傳回多值
end
t={odd()} --表格的元素由 odd() 函數產生
print(table.unpack(t)) --輸出 2 4 6 8 10
上例中先呼叫自訂的 odd() 函數, 用其傳回值來當元素, 再呼叫 table.unpack() 函數來拆解表格.
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
(6) function (函式)
Lua 的函數跟 table 一樣是個物件, 它其實是用 table 建構的. Lua 提供豐富的內建函數, 也可以利用
function 保留字來自定函式以便將演算邏輯抽象化 (abstract). 內建函數中最常用的是 print(), 用來在
螢幕上輸出資料. 上面範例都只用了一個參數, 實際上 print() 可以接受多個參數, 各參數用逗號隔開, 輸
出時各參數會以 tab 隔開 (8 個空格), 例如 :
name="tony"
print("Name=", name) --輸出 "Name= tony"
print(1,2,3,"abc") --輸出 "1 2 3 abc"
Lua 的函式屬於第一級函式 (first-class function), 亦即, 函式可以像數值或字串等一般的值一樣被指
派給一個變數儲存在資料結構中, 例如 :
a=print --將系統函數 print() 指派給變數 a
a("ok") --輸出 ok
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
函數也可以當作引數傳遞給另外一個函式, 或者被當成回傳值傳回給呼叫者, 當然也就具有閉包
(closure) 性質了. 除了 Lua 外, 其他具有 first-class function 功能的語言有 Python, PHP,
Javascript, 以及 Ruby 等.
# Wiki : first-class function
函式的宣告包括 scope(=local, 可有可無), function name, argument(可有可無), body, return value
(可有可無), 與 Javascript/PHP 不同的是, Lua 語法用 end 標誌函式終點, 不用大括號 (已被用在
table) :
scope name(arguments)
body
return values
end
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
當傳入比宣告之參數還要多的引數時, 多餘的引數會被丟棄; 反之, 若傳入之引數比參數少, 那些沒有傳
入引數之參數值預設為 nil. 例如 :
function f(x,y)
print(x,y)
end
則 :
f(1,2,3,4) --輸出 1 2
f(1) --輸出 1 nil
函數即使沒有參數, 呼叫它時也需要小括弧, 例如 func1(), 但有一個例外, 就是當函數只有一個參數而且此參數是
字串或表格時, 可以不用小括弧, 例如 :
print "I love you" --輸出 I love you
print {name="Tony"} --輸出 table: 0075e350
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
Lua 函數不能像 PHP 那樣在參數列中賦予參數預設值, 不過可以用 or 運算子來模擬預設值, 例如 :
function inv(a)
local a=a or 0 --用 or 模擬預設值=0
return -a
end
print(inv()) --輸出 0
print(inv(2)) --輸出 -2
此例中的自訂函數 inv() 會回傳相反數, 當沒有傳入參數時, 區域變數 a 為 nil, 照 or 運算規則, 若第一
運算元為 false/nil, 就傳回第二運算元 0, 達到模擬預設值目的.
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
Lua 的函數還有一個其他語言所沒有的特性, 就是 Lua 函數可以傳回多個回傳值. 例如內建函數
string.find() 就會傳回兩個整數值, 此函數用來在字串中尋找子字串, 其兩個傳回值分別代表所找到之
第一個子字串之開始與結束索引, 例如 :
str="LuaLua"
print(string.find(str, "Lua")) --輸出 1 3
s, e=string.find(str, "Lua") --利用多重指派取得兩個傳回值
print(s, e) --輸出 1 3
在自訂函數中傳回多值時, 各值以逗號隔開即可, 呼叫時用多重指派取得各傳回值, 例如 :
function myfunc() {
local a, b, c, d
--do somthing
return a,b,c,d
end
w,x,y,z=myfunc()
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
Lua 函數也提供不定長度參數功能 (variadic), 參數列使用 ... 來表示一個不確定長度的串列, 它相當於
是一個會傳回多值得函數, 可以用 print(...) 顯示其傳回值, 例如 :
function sum(...)
local s=0
for i,v in ipairs{...} do --呼叫內建函數 ipairs() 拆解陣列 {...}
s=s+v
end
return s
end
print(sum(1,2,3,4,5)) --輸出 15
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
資料型態 (data types) 與運算子 :
Lua 沒有直接支援名稱引數 (named argument), 但是可以用表格來模擬, 例如 :
function profile(args)
print(args.name)
print(args.gender)
print(args.age)
print(args.phone)
end
profile({name="Tony",gender="male",age=50,phone="0911092288"})
因參數為表格或字串時, 函數呼叫可以略去小括弧, 故下面這樣也可以 :
profile{name="Tony",gender="male",age=50,phone="0911092288"}
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
運算子的優先順序 :
在不用小括弧限制之下, Lua 運算子的優先順序如下 :
順序 運算子
1 (最低) or
2 and
3 < > <= >= ~= ==
4 ..
5 + - (減)
6 * / %
7 not # -(負)
8 (最高) ^
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
流程控制 :
(1). 判斷 :
Lua 的判斷式語法如下 :
判斷式 語法 範例
單向
(單條件)
if 條件式 then
敘述
end
if score >= 60 then
print ("及格")
end
雙向
(單條件)
if 條件式 then
敘述
else
敘述
end
if score >= 60 then
print ("及格")
else
print ("不及格")
end
巢狀
(多條件)
if 條件式 then
敘述
elseif 條件式 then
敘述
else
敘述
end
if score >= 90 then
print ("優等") elseif score >= 80 and score < 90 then
print ("甲等")
elseif score >= 70 and score < 80 then
print ("乙等")
else
print ("丙等")
end
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
流程控制 :
(2). 迴圈 :
Lua 只有 for 與 while 兩種迴圈, 沒有 do while 迴圈. 注意 while 迴圈必須控制條件式設定終止條件,
以免成為無窮迴圈. 如果要拜訪表格元素, 可以使用內建函數 pairs() 來取得每一組鍵-值對.
迴圈 語法 範例
for 迴圈
(確定次數)
for 起始值, 終止值 do
敘述
end
local sum=0
for i=1,10 do
sum=sum + i
end
for 迴圈
(遍歷表格)
for key,value in pairs(表格) do
敘述
end
local t={name="Tony",age=50}
for key,value in pairs(t) do
print(key, value)
end
while 迴圈 (不確定次數)
while 條件式 do
敘述
條件運算式
end
local sum=0 local i=1
while i <= 10 do
sum=sum + i i=i + 1
end
print(sum)
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
安裝 Corona SDK
https://coronalabs.com/
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
進入 Corona SDK
新專案
已存在專案
專案列表
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
進入 Corona SDK (空程式段)
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
進入 Corona SDK (預設模擬器)
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
安裝 IDE
VIM
Sublime Text
Koneki (http://www.eclipse.org/projects/archives.php#installation)
Console
記事本
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
安裝圖形佈局介面 http://www.nerderer.com/Gumbo
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
安裝圖形佈局介面
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
使用Web介面測試 lua 語法 http://www.lua.org/demo.html
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
開啟 Corona SDK App
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
設定 Corona SDK App 名稱和螢幕解析度
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
開啟 Corona SDK App 資料夾
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
Corona SDK App 程式區 & 資料檔架構
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
Corona SDK App 程式區 & 資料檔架構
main.lua
Corona SDK 用來開發行動應用的程式語言是 LUA 語言,LUA 是葡萄牙語中「Luna」
(月亮)的意思。它被發明出來是要成為一個很容易嵌入其它語言中使用的語言。所以它
的特色是小,便捷,嵌入 (這目標聽起來很像 JAVA 語言是不是?) 最早的 LUA 體積小、
啟動速度快。它用標準 C 語言編寫並以原始碼形式開放,編譯後僅僅一百餘K,可以很方
便的嵌入別的程式裡。這個 main.lua 就是整個 project 的核心程式,也是未來我們要撰寫
程式最主要的檔案。等一下我們再來看 Hello World! 它程式的內容。
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
Corona SDK App 程式區 & 資料檔架構
build.settings
這個檔案裡放著 Corona Project 最後要編譯到用戶裝置裡面時,一些與目標平台(我指
的是 android 或 iOS)相關的設定值,例如:在 android 系統上你需要得到的授權
permissions,或是像在 iOS 平台,針對 iPhone/iPad/iPhone5 等不同裝置上要顯示的
Icon 圖檔等等。另外,你的應用程式是『直式』portrait或是『橫式』landscape,也是
在這裡設定。 settings =
{
iphone =
{
plist =
{
CFBundleIconFile = "Icon.png",
CFBundleIconFiles = {
"Icon.png",
"Icon@2x.png",
"Icon-72.png",
},
},
}
}
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
Corona SDK App 程式區 & 資料檔架構
config.lua
這個檔案裡放著一些你程式執行時要用到的設定值,例如:
動態內容縮放 Dynamic Content Scaling。
動態內容對齊 Dynamic Content Alignment。
動態內容屬性 Dynamic Content Properties。
動態圖形解析度 Dynamic Image Resolution。等等
Dynamic Content 技術是 Corona SDK 為了配合各種不同裝置,不同營幕尺吋,所提出的解決方案。
譬如:早期 iPhone 剛推出時是寬乘長各 320 x 480 個像素(點)的裝置,到現在 iPhone5 上面已經有寬
乘長各640 x 1136 的像素(點)。如何寫一套程式,就能滿足各個不同裝置的解析度,這個 config.lua 設
定有很大的幫助。
application =
{
content =
{
width = 320,
height = 480,
scale = "letterbox" -- zoom to fill screen, possibly cropping edges
},
}
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
Corona SDK 程式檔
Corona 初探 Lua 語言,
玩跨平台(iOS & Android) 行動裝置開發工具
執行 Corona SDK App 模擬器
Golang 入門初體驗

Corona 初探 lua 語言,玩跨平台(iOS & android) 行動裝置開發工具

  • 1.
    Corona 初探 Lua語言,玩跨平台 (iOS & Android) 行動裝置開發工具
  • 2.
    學習主題 • 社群成立目的簡介 • 自我介紹與哈啦 •功力複習 • 程式實作(Corona SDK) • 問題與交流
  • 3.
    個人簡介 諸葛魔斌 工作室:諸葛魔斌科技創作室 學歷:高應大---工管系(非資訊科系) E-Mail:chugermobin@gmail.com 官方網站:http://twcts.com Facebook:https://goo.gl/volM7Z 粉絲團 :https://goo.gl/LI08wh 社群 :https://goo.gl/kjCsz1 Line(id) :http://goo.gl/ayGW7d Line@ :http://goo.gl/pQHjWH Line Bot :http://goo.gl/ljdxfV Play商店:http://goo.gl/CkVdsd App Store:http://apple.co/1Qehd64 專長:VB(VBA)、C#、Java(Android)、Swift(iOS)、PHP、Python、Conrona、 Golang、Unity、MySQL、FreeBSD、Server架設、CAD 、 …… 楊政斌
  • 4.
    學習程式的歷程 學生時期:打電動,沒有日夜的界限 二專畢業:初次接觸 dBase、Lotus 使用 Clipper 做經銷存、應收付帳系統 工作階段1:接觸 Office,開始使用Excel(Lotus) 工作階段2:品保工作,自學圖表、函數、VBA,做出自動化品管系統 興趣展開:自學VB,製作ERP系統,接觸Linux、FreeBSD,自學架設Server  諸葛魔斌誕生 大學時期:半自學 Android App(Java)、C#、iOS App(Swift) 工作轉變:成立諸葛魔斌科技創作室,接案學習,救國團電腦資訊講師 實績:
  • 5.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 Lua 是一個輕量級的程式語言,該語言是由巴西的 Computer Graphics Technology Group (Tecgraf) 這家公司的員工 Roberto Ierusalimschy, Luiz Henrique de Figueiredo, and Waldemar Celes 等人所創造的。 在 1977 年到 1992 年之間,巴西對電腦軟硬體進行了嚴格的貿易管制保護措施,很多需要電腦軟 硬體的公司無法買到國外的軟硬體,於是 Tecgraf 這家主攻「電腦繪圖與使用者介面」的公司就只 好自行發展「程式語言與開發工具」,並且提供給客戶使用。 在設計出 Lua 之前,Tecgraf 其實已經創造過 SOL (Simple Object Language) 與 DEL (data- entry language) 這兩個程式語言,但這兩個語言並沒有甚麼「流程控制」的語法,於是他們吸取 了 SOL 與 DEL 的設計經驗,然後再參考了 「Modula 語言的 控制結構 (if, while, repeat/until)」, 以及 「CLU 語言的 (多重指定、多傳回值) 等特性」,還有 「SNOBOL、AWK 中的字典 (associative arrays) 概念」,最後創造出了一種語法非常簡易的語言,那就是 Lua。 為何叫做 Lua 呢?Lua 一詞是葡萄牙語中「Luna」(月亮)的意思,因為其前身 SOL 語言的葡萄 牙語意義為「太陽」,所以下一個語言就自然叫做「月亮」囉!
  • 6.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 Lua 的語法非常的簡單,其 BNF 語法寫起來只有一頁,因此可以說是世界上最簡單的語言之一 (雖 然 LISP 的語法比 Lua 更簡單,其 BNF 應該只要兩三行就寫完了,但是寫起來卻很不容易閱讀; 而 Lua 則是容易讀容易寫,但是 BNF 語法就比 LISP 稍長了一些)。 由於這種簡易的特性,後來 Lua 被廣泛使用在各種遊戲引擎裏做為「腳本語言」(Script Language) 使用,列表如下: 2D 遊戲引擎 : Corona SDK、Love2D、Agen、Blitwizard、Cocos2d-x、EGSL、Grail、MOAI。 2.5D 遊戲引擎 : Lavgine。 3D 遊戲引擎 : Baja、Glint 3d、Irrlicht、Leadwerks、Spring RTS、Luxinia、Polycode、 Cryengine。 另外、Lua 也常被各式各樣需要腳本語言的工具軟體使用,像是 Damn Small Linux、Wikipedia template engine、Wireshark、Nginx、LuaTeX、Adobe Photoshop Lightroom 等軟體裏都有 內嵌 Lua 腳本語言。
  • 7.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 Lua 語言特色摘要如下 : Lua 是動態語言 (Dynamic) : 亦即它是在執行時期 (Runtime) 才做型別檢查, 所以宣告變數時不需要宣告其資料型別, 而且執行中 可任意變換其型別. 其他知名的語言如 Javascript, PHP, Python, Ruby 等都是動態語言. 而 Java 與 C 等靜態語言則是在編譯時期就做型別檢查, 宣告變數時必須同時指定其資料型別, 而且宣告後不 能再更換為其他型別, 若賦予之資料與宣告型別不符就會產生編譯錯誤. Lua 是弱型別語言 (Weak typing) : 弱型別語言允許一個變數在相對應的記憶體區域中可以存放不同類型的資料, 而強型別語言則不可 以. 弱型別語言的型別推斷功能可以進行較大程度的隱性 (自動) 型別轉換, 反之, 強型別語言的自動 型別轉換則較少, 強弱是相對的, 並非絕對. 注意, 動態語言不一定是弱型別語言, 例如動態語言的 Python 與 Ruby 就屬於強型別語言; 而靜態語言的 Java 也有自動型別轉換, 但是屬於強型別語言.
  • 8.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 Lua 語言特色摘要如下 : Lua 擴展能力強 (Extensible) : Lua 的核心非常精簡小巧, 語法簡潔優美, 類似簡化的英文, 其強大的功能來自於易擴展性, 主要是透 過以 Lua 本身內建或用 C/C++ 編寫的外部函式庫來達成, 也具有 Java, Fortran, Smalltalk, Ada 的 API 介面來擴展函式庫. Lua 可嵌入其他語言中 (Embedable) : Lua 可以嵌入到 C/C++, Java, C#, Python, Ruby, Perl 等其他語言中, 做為其函式庫使用. 而且 Lua 可以雙向呼叫 (bi-directional), 亦即可由 Lua 呼叫宿主語言函式, 也可以由宿主語言呼叫 Lua 函式, 一般腳本語言通常只專注在呼叫外部函式庫. Lua 是跨平台語言 (Portable) : Lua 以 ANSI C/C++ 語言編寫而成, 可在多數作業系統上執行, 甚至在嵌入式系統如手機 Android 與 iPhone, 遊戲機 PSP, PS3, 甚至以 WiFi 晶片 ESP8266 為基礎的 NodeMCU 上也可以執行, 可 移植性極高.
  • 9.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 Lua 的優勢是執行速度快, 語法簡單學習曲線不陡峭 (參考 http://yhhuang1966.blogspot.tw/2015/07/lua_14.html) (參考 http://coronaintaiwan.blogspot.tw/2013/04/blog-post.html) 區塊 (chunk 或 block) : Lua 程式的一段陳述 (statement) 稱為 chunk, 它可以是指一條指令, 也可以是一群指令. 例如 : a=100 print(a) 或者 a=100 print(a)
  • 10.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 Lua 的優勢是執行速度快, 語法簡單學習曲線不陡峭 區塊 (chunk 或 block) : 每條指令間不須像 Javascript 或 PHP 那樣用分號結尾, 直接跳行即可, 但用分號結尾也是可以的 (行尾的分號對 Lua 而言是可有可無的, optional), 例如 : a=100; print(a); 但如果兩條敘述要寫在同一行就必須用分號隔開 (不是用逗號), 例如 : a=100; print(a)
  • 11.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 Lua 的優勢是執行速度快, 語法簡單學習曲線不陡峭 區塊 (chunk 或 block) : 最常見的區塊是函數 (function end), 迴圈 (for end, while end, repeat end), 判斷 (if end), 以及匿 名區塊 (do end), 在這四種區塊內的變數都是自成一個單元, 享有相同的作用域或環境 (scope, context) : function function1() --do something end for a=1, 100, 5 do --do something end if a<=10 do --do something end do --do something end 注意, 在 Lua 解譯器的交談模式中, 每一行完 整的指令就是一個 chunk, 所以這一行定義的 區域變數跳到下一行時是新的一個 chunk, 已 經超出其作用域 (scope) 而無法存取, 執行的 結果將不受上一行區域變數之影響. 此問題可 用 do end 區塊解決, 包含在此區塊內的陳述 都屬於同一 chunk.
  • 12.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 程式註解 : Lua 使用開頭的兩個 dash (--) 作為單行註解符號 (一直到行尾), 例如 : --這是單行註解行 多行註解則是使用兩個 dash 與雙中括號 --[[ 開頭, 一直到下一個雙中括號為止, 所包含的區域解譯 器會略過不予處理 : --[[這是 多行 註解]]
  • 13.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 程式註解 : 例如下列範例 test.lua : --[[ print ("Hello World!") ]] print ("Hello World!") 執行此程式只會印出一行 "Hello World!", 因為第一個 print 指令被註解掉了不會執行. 在程式開發過程中, 為了除錯方便常會使用多行註解來控制某一段程式是否要執行, 測試完畢後又要 把 --[[ 與 ]] 分別去掉, 有個取巧的辦法可以解決此麻煩, 就是在結尾中括號前也加上雙 dash : --[[ print ("Hello World!") --]] print ("Hello World!")
  • 14.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 程式註解 : 這樣當要取消註解, 讓原先被註解掉的程式碼恢復執行時, 只要在註解開頭處再加一個 dash 即可 (因為 ---[[ 中前面的兩個 dash 把這行變成單行註解, 迫使結尾的 --] 單飛為單行註解, 多行註解破 功) : ---[[ print ("Hello World!") --]] print ("Hello World!") 這樣註解頭失去多行註解功能, 而註解尾變成單行註解, 不用刻意去除. 這個程式會印出兩行 "Hello World!". 但中括號有時令人覺得眼花撩亂, 一律使用 -- 其實會比較整齊與單純.
  • 15.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 識別字 (Identifier) 與保留字 : 識別字用來指派變數或函式名稱, Lua 識別字的限制與 Javascript 一樣, 只能使用英文字母, 數字, 以及底線之組合, 但是第一個字元不可以是數字, 所以 2au 不是合法的識別字. 此外雖然可以用底線 開頭, 但是因為 Lua 解譯器內部使用以底線開頭的變數, 特別是用底線開頭, 後面是大寫字母組成的 識別字, 例如 _VERSION (這是 Lua 特殊用途的保留字), 所以最好不要用底線開頭來命名變數, 以免 與系統衝突. 另外, Lua 有 22 個保留字, 這些都不能拿來當識別字 : local nil not or and if then else elseif for end in do while until repeat break true false function return goto
  • 16.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 識別字 (Identifier) 與保留字 : 其中 nil 即 Javascript 或 PHP 的 null 或 NULL, 即無值之意. 被設為 nil 的變數會在記憶體管理下 一次掃描時被垃圾回收而消失. 相較於 Javascript 有 29 個保留字, Python 的 33 個, Java 的 50 個, PHP 的 53 個, 而 C# 高達 87 個, Lua 卻只有 22 個, 可見 Lua 有多精簡. Lua 是有分大小寫的 (case-sensitive), 所以 and 是保留字不能用, 但 AND, And 卻是合法的識別字.
  • 17.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 全域變數與區域變數 : 只要不是用 local 宣告的變數都是全域變數, 即使它位於函數或迴圈等區塊中, 例如 : a=100 全域變數一經賦值後就會一直存在記憶體中, 直到被設為 nil 才會被記憶體管理回收. 存取未賦值的 全域變數會得到 nil. 全域變數實際上會放在名為 _G 的特殊表格中 (Table, 即關聯式陣列, 是 Lua 唯 一的資料結構, 所有的變數, 函式都是以 table 來儲存), 安全性較高.
  • 18.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 全域變數與區域變數 : 區域變數是以 local 宣告的變數, 其作用域 (scope) 僅限於所在之區塊 (block) 內, 例如在函式, 分岐控 制, 迴圈或 do end 結構中使用的變數應該宣告用 local 宣告為區域變數. 區塊中的區域變數會掩蓋同 名的全域變數 (即不會存取到同名之全域變數), 意即更改區域變數之值不會影響全域變數的值. 當程式 區塊執行結束時, 區塊內的區域變數就會被記憶體管理自動回收 (因此不需要刻意在區塊末尾將其設為 nil). 唯一的例外是, 如果全域變數有參考到區域變數, 則此區域變數不會隨著區塊結束而被回收, 例如 : a=1 function myfunc() local b=2 a=b --全域變數 a 參考到區域變數 b end myfunc() print(b) --輸出 nil (無法存取到區域變數) print(a) --輸出 2
  • 19.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 全域變數與區域變數 : 由於全域變數 a 在函數內參照了區域變數 b, 使得 b 被全域化, 因此在呼叫函數 myfunc() 後, 原本是區 域變數的 b 無法正常地被垃圾回收而留存在記憶體中 (但在上層全域卻看不到), 成為垃圾回收的漏網 之魚. 這種參照方式要盡可能避免, 否則可能因 memory leak 造成程式崩潰. 除非必要不要使用全域變數, 要盡量使用區域變數, 因為它的執行速度比較快, 而且在記憶體運用上也 較有效率, 當它到達作用域盡頭時就會失去作用而被記憶體管理自動回收. 因為當 Lua 解譯一個變數時, 如果它前面有 local 標示為區域變數, 則解譯器會在目前的區域中尋找此變數, 找不到就是 nil; 如果沒 有 local, 就會往上一層去找, 直到最上層為止, 找不到才是 nil, 因此全域變數要花較多時間尋找, 會影 響執行效率, 所以除非是必要的全域變數, 盡量使用區域變數. 例如 : local a=1 local b=2 if a print(a) --> 輸出 1 local a=10 -- then 區塊內的區域變數, 不影響外面的區域變數 a print(a) --> 輸出 10 end print(a) --> 輸出 1 print(b) --> 輸出 2
  • 20.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 多重指派 (multiple assignment) : Lua 跟 Python 一樣具有多重指派語法, 可以在一個陳述中同時為多個變數賦值, 各變數以逗號隔開, 例如在交談模式中 : > do >> local a,b,c=1,2,3 >> print(a,b,c) >> end 1 2 3 但如果賦值不足, 則未賦值之變數預設為 nil, 例如 : > do >> local a,b,c=1,2 >> print(a,b,c) >> end 1 2 nil
  • 21.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 多重指派 (multiple assignment) : 若賦值超過變數之數目, 多出來的值會被視而不見略過. 多重指派讓資料交換變得很簡潔, 只需要一條 指令即可 : local a,b=1,2 a,b=b,a --交換後 a=2, b=1
  • 22.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : Lua 是動態弱型別語言, 其變數是無型態的 (typeless), 宣告時不需要指定資料型態, 但變數的值當然 有型態, 因為解譯器是靠值的資料型態來動態地配置記憶體. Lua 有八種資料型態 : (1). nil (無值) (2). boolean (布林) (3). number (數值) (4). string (字串) (5). table (表格, 關聯式陣列) (6). function (函式) (7). thread (執行緒) (8). userdata (使用者資料)
  • 23.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 前面六種都是其他語言中常見的型態, 而 thread 與 userdata 則較特殊. 事實上這八種資料都是使用 table 來實作的, 因為 table 是 Lua 唯一的資料結構. 使用者定義資料 userdata 是記憶體中的一個區塊, 用來給 C 函式透過 API 存取資料, Lua 無法建立或操控此資料. 而 thread 是用來指派一個例外的獨立 執行緒, 但這與一般作業系統的 thread 不同, Lua 不支援真正的多執行緒 (先佔式記憶體分享, 因為 ANSI C 不提供), 不過 Lua 透過 coroutine 提供非先佔式或非記憶體分享多執行緒. 而 thread 就是 coroutine 與低層 API 的組合. Lua 有一個內建函數 type() 可用來檢測變數的資料類型, 例如 : print(type(1)) --輸出 number print(type("Tony")) --輸出 string t={} print(type(t)) --輸出 nil (因為是個空的表格) t={name="tony"} print(type(t)) --輸出 table
  • 24.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 以下整理最常用的字串, 數值, 布林值, 與無值 nil. (1) nil nil 相當於 Javascript 的 null, 表示一個變數無值, 即尚未初始化. 一個變數只宣告而未賦值, 預設就是 nil. 全域變數一經宣告就會存在於記憶體中, 除非我們把它設為 nil 才會被垃圾收集機制刪除. (2). boolean 在 Javascript 中 true 與 1, false 與 0 是同義的, 但在 Lua 卻不同, Lua 的布林值只有 true 與 false 兩種, 1/0 並非 true/false 的別名, 配合 not, and 與 or 運算用在條件控制的邏輯判斷上. 但 Lua 的條件 控制並非只能依賴這兩個布林值, boolean 以外的型態都可以用在邏輯判斷, 但除了 false 與 nil 在邏 輯上為假外, 其他均為真, 例如 :
  • 25.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : b=0.22 if (b) then print("true") --> 印出 true else print("false") end 但是要注意, Lua 的 and 與 or 運算結果有點特別, 採用所謂 shortcut evaluation (捷徑估值法), 其傳 回值不一定是 true 或 false, 而是取決於第一個運算元. 如果 and 運算的第一個運算元是 false 或 nil, 就直接傳回第一個運算元 (即 false 或 nil); 否則傳回第二運算元, 例如 : print(nil and 5) --> 印出 nil (第一個是 nil/false 就傳回 nil/false) print(false and "OK") --> 印出 false (第一個是 nil/false 就傳回 nil/false) print(2.2 and "OK") --> 印出 OK (第一個不是 nil/false 就傳回第二個)
  • 26.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 其次, 如果 or 運算的第一個運算元是 nil 或 false, 就直接傳回第二個運算元, 否則就傳回第一個運算元, 例如 : print(nil or 5) --> 印出 5 (第一個是 nil/false 就傳回第二個) print(false or "OK") --> 印出 OK (第一個是 nil/false 就傳回第二個) print(2.2 or "OK") --> 印出 2.2 (第一個不是 nil/false 就傳回自己) 運算元最好只使用 true, false/nil 來進行運算, 以免邏輯判斷出現非預期結果. 與布林值有關的除了邏輯運算外還有關係運算子 : > (大於) < (小於) >= (大於等於) <= (小於等於) == (等於) ~= (不等於)
  • 27.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 與其他語言比較不同的是 Lua 用 ~= 表示不等於 (C/Java/PHP 等使用 !=), 例如 : if (nil ~= false) then print("不相等") end --> 印出 不相等 if (2.2>0) then print("正數") end --> 印出 正數 注意, 資料型態不同的變數不能使用關係運算子加以比較, 特別是比大小運算子 ( >, <, >=, <=) 會出現 錯誤訊息. 例如 : > if ("OK">0) then print("正數") end stdin:1: attempt to compare number with string stack traceback: stdin:1: in main chunk [C]: in ?
  • 28.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 必須是相同資料型態才能進行含有大小的比較, 例如 : if ("smart">"rich") then print("smart is better") --> 印出 smart is better else print("rich is better") end 而 == 與 ~= 這兩個與大小無關的運算即使資料型態不同也不會出現錯誤, 例如 : if ("knowledge" == 0) then print("idiot") else print("expert") end --輸出 "expert" 事實上, == 與 ~= 運算會先去看兩個運算元資料型態是否相同, 然後再去比較其內容. 前者 == 會先看資 料型態是否相同, 如果不同就直接傳回 false (不用比內容啦!), 型態相同才去比較內容, 相同傳回 true, 不同傳回 false, 例如 :
  • 29.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : if 1==true then --資料類型不同傳回 false print("same") else print("different") --輸出 different end if ("power" == "power") then print("power is power") else print("power is not power") end --輸出 "power is power" if ("knowledge" == "power") then print("knowledge is power") else print("knowledge is not power") end --輸出 "knowledge is not power"
  • 30.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 而 ~= 運算只要型態不同, 就直接傳回 true 了; 若型態相同才去比內容, 相同傳回 false, 不同傳回 true, 例如 : if ("money" ~= 0) then print("have money") else print("have no money") end --輸出 "have money" if ("knowledge" ~= "power") then print("knowledge is not power") else print("knowledge is power") end --輸出 "knowledge is not power" 對於 table, function 等物件, 變數儲存的是參考 (指向實際的資料儲存位置), == 與 ~= 運算比較的是其 參考, 例如 :
  • 31.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : t1={1,2,3} t2={1,2,3} if t1==t2 then print("same") else print("different") --輸出 different (t1 與 t2 是不同參考) end t3=t1 --複製參考, t3 與 t1 指向同一個 table if t1==t3 then print("same") --輸出 same else print("different") end 上例之 t1 與 t2 雖然內容相同, 但參考不同, 故 t1==t2 運算傳回 false, 而 t3=t1 是複製參考, 兩者指向 同一個 table, 故 t1==t3 傳回 true.
  • 32.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : (3). number 數值方面, 可以使用 10/16 進位整數, 小數, 科學表示法來表示, 但 Lua 並沒有整數型態, Lua 的數值一 律使用雙準度浮點數儲存 (IEEE 754). 例如 : print(2000) --> 印出 2000 print(3.14159) --> 印出 3.14159 print(2e3) --> 印出 2000.0 print(2E-2) --> 印出 0.02 雖然使用浮點數來表示整數, 但在 Lua 不會產生進為誤差 (rounding errors). 科學表示法的指數用 e 或 E 都可以. 如果要表示 16 進位數, 數值就要以 0x 或 0X 開頭, 例如 : print(0xff) --> 印出 255
  • 33.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 數值的運算子有如下七個 : + (加) - (減) * (乘) / (除) % (餘數) ^ (次方) - (單元運算, 負數), 例如 : print(1/2) --> 印出 0.5 print(5%3) --> 印出 2 print(2^10) --> 印出 1024.0 print(-2) --> 印出 -2 當字串與數字混合運算時, Lua 會進行自動轉型, 將數字字串轉成數字再運算, 例如 : print(1+"100") --輸出 101.0 print(1+".1") --輸出 1.1
  • 34.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : (4). string Lua 的字串與 Java 一樣是不可變的 (immutable), 對字串的操作事實上是產生另外一個新字串. 字串 的用法跟 Javacript 或 PHP 類似, 可用雙引號或單引號括起來, 除此之外, 也可以用兩個中括號對 (主 要用在跨行的長字串), 例如 : a="Hello" b='World' print(a,b) --> 印出 Hello World print([[Hello World!]]) --> 印出 Hello World! 如果字串中有引號時, 只要秉持成對 (matching) 與替換 (alternate) 原則就不會弄錯, 例如 : print("This is Tony's book.") --> 印出 This is Tony's book.
  • 35.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 這裡所有格必須用單引號, 因此整個字串要用雙引號括起來. 如果用單引號就會出錯 : print('This is Tony's book.') --> 錯誤! stdin:1: ')' expected near 's' 如果堅持用單引號, 則所有格必須用倒斜線跳脫 : print('This is Tony's book.') --> 印出 This is Tony's book. 或者乾脆用雙重中括號免得麻煩 : print([[This is Tony's book.]]) --> 印出 This is Tony's book.
  • 36.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 常用的跳脫字元如下 : " : 雙引號 ' : 單引號 n : 換行 r : 回車 : 倒斜線 字串也可以用 ASCII 編碼來表示 (如果覺得這樣很有趣, 又不會太麻煩的話), 例如 ABC 的 ASCII 編碼 以十進位表示分別為 65, 66, 67, 所以要印出 "ABC" 可以用倒斜線跳脫 ASCII 碼來表示 : print("656667") --> 印出 ABC
  • 37.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 也可以用十六進位表示, 但要加一個小寫 x (不能用大寫 X) : print("x41x42x43") --> 印出 ABC 參考 : Wiki : ASCII 對於可能會超過一行長字串, 為了編輯的方便需要拆成數行時, Lua 提供兩個方式來輸入長字串, 第一 個是用 [[ 與 ]] 符號來包圍一塊長字串區域, 例如 : a=[[This is a very very very ... long story.]] print(a) 印出的結果與編輯時的樣子相同, 會保留所有的空格.
  • 38.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 第二個方法是用跳脫字元 z 來串接長字串, 例如 : a="This is a very z very z very ... z long story." print(a) --> 印出 This is a very very very ... long story. 可見使用 z 不會保留空格, z 會直接串接到下一行的非空白字元. Lua 取得字串長度是在字串前面加個 "#", 例如 : print(#"ABC") --> 印出 3 a="Hello World!" print(#a) --> 印出 12
  • 39.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 也可以使用內建的 string.len() 函式, 例如 : print(string.len("Hello World!")) --> 印出 12 至於串接字串, 有別於 Javacript 用加號, PHP 用點號, Lua 是用連續兩個點號來串接字串, 例如 : print("Hello".." ".."World!") --> 印出 Hello World! 由於 Lua 是弱型態語言, 當數值字串進行數值運算時會自動進行型態轉換, 例如 : print("12" + 3) --> 印出 15, 會先將 "12" 轉成 12 再加 3. print("4.5e25" * "3") --> 印出 1.35e+026
  • 40.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 但如果不是數值字串, 就會無法轉成數值而發生錯誤, 例如 : > print("1 hundred" + 900) --> 1 hundred 不是數值 stdin:1: attempt to perform arithmetic on a string value stack traceback: stdin:1: in main chunk [C]: in ? 反之, 當數值進行字串運算時, Lua 也會自動將數值先轉成字串再運算, 例如 : print(20 .. 15) --> 印出 2015 注意, 這裡數值與字串串接運算符 .. 之間必須有一個空格, 否則第一個點會被認為是小數點而產生 malformed number 錯誤.
  • 41.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 以上是數值與字串的隱性型別轉換, 顯性的轉換則是利用 tonumber() 與 tostring()函式, 例如 : if (tonumber("2e2") == 200) then print("match") end --> 印出 match if (tonumber("10.5") == 10.5) then print("match") end --> 印出 match
  • 42.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : (5). Table (表格) Lua 的 table 其實就是關聯式陣列 (associative array), 這是 Lua 唯一的資料結構, 所有的資料型態都 是用 table 來實作的, 例如全域變數就是儲存在名為 _G 的特殊表格中, 宣告一個全域變數 a="123" 其 實跟 _G["a"]="123" 是一樣的. 在其他語言中常見的陣列 (array), 串列 (list), 紀錄 (record), 佇列 (queue), 或集合 (set) 等, Lua 都用 table 來實現. Lua 的 table 是用大括號來宣告的 : t={} --> 宣告一個空的表格
  • 43.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 表格是一種關聯式陣列, 所以可以用數字當索引, 也可以用字串當索引, 事實上, 在 Lua 中除了 nil 外, 任何值都可以當 Table 的索引, 例如 : t={} t[0]="peter" t[2]=23 t["2"]=45 -- 這跟 t[2] 無關 t["gender"]="female" print(t[2]) --輸出 23 print(t[2"]) --輸出 45 print(t["age"]) --輸出 nil (無此元素不會出現錯誤, 而是認為新元素賦值 nil)
  • 44.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 當然也可以在宣告時同時賦值, 例如 : t={[0]="peter", [2]=23, ["gender"]="female"} -- 注意喲, 索引必須用中括號 如果索引名稱符合識別字限制 (英數字與底線組合, 不以數字開頭), 則中括號與引號可以省略, 例如 : t={name="peter", age=23, gender="female", _class=0} 所以, 索引 a 與 ["a"] 是同樣的意思, 下列宣告前後都是同一元素, 後者的會蓋掉前者 : t={["a"]=123, a=456} print(t["a"]) --> 印出 456 (被覆蓋了)
  • 45.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : Table 的最後一個元素若跟著逗號是允許的, 例如 : t={1,2,3,} 這對於以迴圈自動產生 Table 元素非常方便, 因為不需要花功夫去除最後一個逗號. 雖然都是關聯式陣列, 但 Lua 的 table 跟 PHP 的關聯式陣列在索引的使用上是不一樣的, 以數值當索 引時, PHP 只能用 0 與正整數當索引, 而 table 的索引則不限於整數, 可以是任何數值, 可用實數, 也可 以是布林值, 例如 : t={} t[2.2]="too small" t[2.2e10]="too big" t[-199.99]="negative" t[true]=true t[false]=false
  • 46.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 對於字串索引, Lua 也提供點符號來存取表格, 這跟物件或紀錄 (record) 的用法是一樣的, 例如 : t={} t.name="peter" -- 相當於 t["name"] t.age=23 -- 相當於 t["age"] t.gender="female" -- 相當於 t["gender"] t._ID1="S1122334455" -- 相當於 t["_ID1"] 注意, 這裡點後面的欄位名稱受識別字命名法規範, 亦即只能用英文字母, 底線與數字之組合, 而且不能 用數字開頭, 例如 t.2xy 是不合法的.
  • 47.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 這種點符號最容易讓人誤解之處是, 點後面的欄位名稱是個字串, t.a 意思是 t["a"], 而不是t[a], t.a 的 a 就是字串 "a", 而 t[a] 的 a 是指一個變數 a, 所以 t[a] 的索引決定於 a 變數的值, 例如 : t={} a="x" t[a]=1 -- 即 t["x"]=1 print(t.a) --> 印出 nil (因為 t.a 就是 t["a"], 並未定義故為 nil) print(t[a]) --> 印出 1 (因為此 a 為變數, t[a] 即 t["x"], 已設為 1) 如果要用 table 來實作一般的陣列, 而非關聯式陣列, 那就略過索引的指定, 直接把元素的值放在中括號 內即可, 例如 : t={1, 2, 3} print(t[0]) --> 印出 nil print(t[1]) --> 印出 1 print(t[2]) --> 印出 2 print(t[3]) --> 印出 3
  • 48.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 如果要知道陣列長度 (即有幾個元素), 跟取得字串長度一樣, 使用 # 運算子即可 : t={"a", "b", "c", 1, 2, 1.7e-34} print(#t) --> 印出 6 但要注意的是, 存取元素時, 索引是從 1 開始算的, 而不是像 Javascript 或 PHP 那樣是從 0 開始, 因為 在不指定索引的情況下, Lua 的整數索引預設是從 1 開始數的, 這在 Lua 是普遍的法則. 要不, 你就得 自行指定索引 (愛從哪開始就從哪開始) : t={[0]=1, [1]=2, [2]=3} print(t[0]) --> 印出 1 print(t[1]) --> 印出 2 print(t[2]) --> 印出 3 print(t[3]) --> 印出 nil (未定義) 但這樣就失去懶人的目的了.
  • 49.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : Lua 允許使用負數做為陣列索引, 但是 # 運算子卻只能計算索引為 1 起始的整數索引元素, 例如 : t={} for i=-5,5 do t[i]=i end print(#t) --輸出 5 表格的元素也是可以是另一個表格, 謂之巢狀表格, 而且可以要多深就有多深, 例如 : t={name="peter", im={qq="1234567890", skype="aaa"}} print(t.im.qq) --> 印出 1234567890 print(t["im"]["skype"]) --> 印出 aaa
  • 50.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 可以用 key 或 index 兩種方式來存取巢狀表格的元素. 表格的元素也可以由函數的傳回值來產生, 例如 : function odd() return 2,4,6,8,10 --傳回多值 end t={odd()} --表格的元素由 odd() 函數產生 print(table.unpack(t)) --輸出 2 4 6 8 10 上例中先呼叫自訂的 odd() 函數, 用其傳回值來當元素, 再呼叫 table.unpack() 函數來拆解表格.
  • 51.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : (6) function (函式) Lua 的函數跟 table 一樣是個物件, 它其實是用 table 建構的. Lua 提供豐富的內建函數, 也可以利用 function 保留字來自定函式以便將演算邏輯抽象化 (abstract). 內建函數中最常用的是 print(), 用來在 螢幕上輸出資料. 上面範例都只用了一個參數, 實際上 print() 可以接受多個參數, 各參數用逗號隔開, 輸 出時各參數會以 tab 隔開 (8 個空格), 例如 : name="tony" print("Name=", name) --輸出 "Name= tony" print(1,2,3,"abc") --輸出 "1 2 3 abc" Lua 的函式屬於第一級函式 (first-class function), 亦即, 函式可以像數值或字串等一般的值一樣被指 派給一個變數儲存在資料結構中, 例如 : a=print --將系統函數 print() 指派給變數 a a("ok") --輸出 ok
  • 52.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 函數也可以當作引數傳遞給另外一個函式, 或者被當成回傳值傳回給呼叫者, 當然也就具有閉包 (closure) 性質了. 除了 Lua 外, 其他具有 first-class function 功能的語言有 Python, PHP, Javascript, 以及 Ruby 等. # Wiki : first-class function 函式的宣告包括 scope(=local, 可有可無), function name, argument(可有可無), body, return value (可有可無), 與 Javascript/PHP 不同的是, Lua 語法用 end 標誌函式終點, 不用大括號 (已被用在 table) : scope name(arguments) body return values end
  • 53.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : 當傳入比宣告之參數還要多的引數時, 多餘的引數會被丟棄; 反之, 若傳入之引數比參數少, 那些沒有傳 入引數之參數值預設為 nil. 例如 : function f(x,y) print(x,y) end 則 : f(1,2,3,4) --輸出 1 2 f(1) --輸出 1 nil 函數即使沒有參數, 呼叫它時也需要小括弧, 例如 func1(), 但有一個例外, 就是當函數只有一個參數而且此參數是 字串或表格時, 可以不用小括弧, 例如 : print "I love you" --輸出 I love you print {name="Tony"} --輸出 table: 0075e350
  • 54.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : Lua 函數不能像 PHP 那樣在參數列中賦予參數預設值, 不過可以用 or 運算子來模擬預設值, 例如 : function inv(a) local a=a or 0 --用 or 模擬預設值=0 return -a end print(inv()) --輸出 0 print(inv(2)) --輸出 -2 此例中的自訂函數 inv() 會回傳相反數, 當沒有傳入參數時, 區域變數 a 為 nil, 照 or 運算規則, 若第一 運算元為 false/nil, 就傳回第二運算元 0, 達到模擬預設值目的.
  • 55.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : Lua 的函數還有一個其他語言所沒有的特性, 就是 Lua 函數可以傳回多個回傳值. 例如內建函數 string.find() 就會傳回兩個整數值, 此函數用來在字串中尋找子字串, 其兩個傳回值分別代表所找到之 第一個子字串之開始與結束索引, 例如 : str="LuaLua" print(string.find(str, "Lua")) --輸出 1 3 s, e=string.find(str, "Lua") --利用多重指派取得兩個傳回值 print(s, e) --輸出 1 3 在自訂函數中傳回多值時, 各值以逗號隔開即可, 呼叫時用多重指派取得各傳回值, 例如 : function myfunc() { local a, b, c, d --do somthing return a,b,c,d end w,x,y,z=myfunc()
  • 56.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : Lua 函數也提供不定長度參數功能 (variadic), 參數列使用 ... 來表示一個不確定長度的串列, 它相當於 是一個會傳回多值得函數, 可以用 print(...) 顯示其傳回值, 例如 : function sum(...) local s=0 for i,v in ipairs{...} do --呼叫內建函數 ipairs() 拆解陣列 {...} s=s+v end return s end print(sum(1,2,3,4,5)) --輸出 15
  • 57.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 資料型態 (data types) 與運算子 : Lua 沒有直接支援名稱引數 (named argument), 但是可以用表格來模擬, 例如 : function profile(args) print(args.name) print(args.gender) print(args.age) print(args.phone) end profile({name="Tony",gender="male",age=50,phone="0911092288"}) 因參數為表格或字串時, 函數呼叫可以略去小括弧, 故下面這樣也可以 : profile{name="Tony",gender="male",age=50,phone="0911092288"}
  • 58.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 運算子的優先順序 : 在不用小括弧限制之下, Lua 運算子的優先順序如下 : 順序 運算子 1 (最低) or 2 and 3 < > <= >= ~= == 4 .. 5 + - (減) 6 * / % 7 not # -(負) 8 (最高) ^
  • 59.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 流程控制 : (1). 判斷 : Lua 的判斷式語法如下 : 判斷式 語法 範例 單向 (單條件) if 條件式 then 敘述 end if score >= 60 then print ("及格") end 雙向 (單條件) if 條件式 then 敘述 else 敘述 end if score >= 60 then print ("及格") else print ("不及格") end 巢狀 (多條件) if 條件式 then 敘述 elseif 條件式 then 敘述 else 敘述 end if score >= 90 then print ("優等") elseif score >= 80 and score < 90 then print ("甲等") elseif score >= 70 and score < 80 then print ("乙等") else print ("丙等") end
  • 60.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 流程控制 : (2). 迴圈 : Lua 只有 for 與 while 兩種迴圈, 沒有 do while 迴圈. 注意 while 迴圈必須控制條件式設定終止條件, 以免成為無窮迴圈. 如果要拜訪表格元素, 可以使用內建函數 pairs() 來取得每一組鍵-值對. 迴圈 語法 範例 for 迴圈 (確定次數) for 起始值, 終止值 do 敘述 end local sum=0 for i=1,10 do sum=sum + i end for 迴圈 (遍歷表格) for key,value in pairs(表格) do 敘述 end local t={name="Tony",age=50} for key,value in pairs(t) do print(key, value) end while 迴圈 (不確定次數) while 條件式 do 敘述 條件運算式 end local sum=0 local i=1 while i <= 10 do sum=sum + i i=i + 1 end print(sum)
  • 61.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 安裝 Corona SDK https://coronalabs.com/
  • 62.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 進入 Corona SDK 新專案 已存在專案 專案列表
  • 63.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 進入 Corona SDK (空程式段)
  • 64.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 進入 Corona SDK (預設模擬器)
  • 65.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 安裝 IDE VIM Sublime Text Koneki (http://www.eclipse.org/projects/archives.php#installation) Console 記事本
  • 66.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 安裝圖形佈局介面 http://www.nerderer.com/Gumbo
  • 67.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 安裝圖形佈局介面
  • 68.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 使用Web介面測試 lua 語法 http://www.lua.org/demo.html
  • 69.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 開啟 Corona SDK App
  • 70.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 設定 Corona SDK App 名稱和螢幕解析度
  • 71.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 開啟 Corona SDK App 資料夾
  • 72.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 Corona SDK App 程式區 & 資料檔架構
  • 73.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 Corona SDK App 程式區 & 資料檔架構 main.lua Corona SDK 用來開發行動應用的程式語言是 LUA 語言,LUA 是葡萄牙語中「Luna」 (月亮)的意思。它被發明出來是要成為一個很容易嵌入其它語言中使用的語言。所以它 的特色是小,便捷,嵌入 (這目標聽起來很像 JAVA 語言是不是?) 最早的 LUA 體積小、 啟動速度快。它用標準 C 語言編寫並以原始碼形式開放,編譯後僅僅一百餘K,可以很方 便的嵌入別的程式裡。這個 main.lua 就是整個 project 的核心程式,也是未來我們要撰寫 程式最主要的檔案。等一下我們再來看 Hello World! 它程式的內容。
  • 74.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 Corona SDK App 程式區 & 資料檔架構 build.settings 這個檔案裡放著 Corona Project 最後要編譯到用戶裝置裡面時,一些與目標平台(我指 的是 android 或 iOS)相關的設定值,例如:在 android 系統上你需要得到的授權 permissions,或是像在 iOS 平台,針對 iPhone/iPad/iPhone5 等不同裝置上要顯示的 Icon 圖檔等等。另外,你的應用程式是『直式』portrait或是『橫式』landscape,也是 在這裡設定。 settings = { iphone = { plist = { CFBundleIconFile = "Icon.png", CFBundleIconFiles = { "Icon.png", "Icon@2x.png", "Icon-72.png", }, }, } }
  • 75.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 Corona SDK App 程式區 & 資料檔架構 config.lua 這個檔案裡放著一些你程式執行時要用到的設定值,例如: 動態內容縮放 Dynamic Content Scaling。 動態內容對齊 Dynamic Content Alignment。 動態內容屬性 Dynamic Content Properties。 動態圖形解析度 Dynamic Image Resolution。等等 Dynamic Content 技術是 Corona SDK 為了配合各種不同裝置,不同營幕尺吋,所提出的解決方案。 譬如:早期 iPhone 剛推出時是寬乘長各 320 x 480 個像素(點)的裝置,到現在 iPhone5 上面已經有寬 乘長各640 x 1136 的像素(點)。如何寫一套程式,就能滿足各個不同裝置的解析度,這個 config.lua 設 定有很大的幫助。 application = { content = { width = 320, height = 480, scale = "letterbox" -- zoom to fill screen, possibly cropping edges }, }
  • 76.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 Corona SDK 程式檔
  • 77.
    Corona 初探 Lua語言, 玩跨平台(iOS & Android) 行動裝置開發工具 執行 Corona SDK App 模擬器
  • 78.