學習 Lua 對於瞭解 Javascript 的人來講就是小菜一碟,Tyler Neylon 寫了三篇文章來解釋其中的緣由,這是其中的第一篇。javascript
這是經過 Javascript 來學習 Lua 系列文章的第一篇,一共有三篇,第二篇和第三篇。
登錄 Tyler 的免費的網絡廣播頻道收聽 Lua 能作什麼?php
Lua 是一門優雅的,可移植的,高效的而且異常靈活的語言。全部可以編譯 C 語言的操做系統都能運行 Lua,這是一些跨平臺的框架,好比 Corona SDK 和 Love game engine,選擇 Lua 的緣由。Lua 的運行速度很快,足夠用來開發遊戲——憤怒的小鳥的最初是用 Lua 編寫的。 Lua 能和其餘的語言很好的融合在一塊兒,它做爲腳本語言,在 Adobe lightroom 項目中有出色的表現。我認爲 Lua 的設計很優美,用起來也很是的舒服。css
對於已經瞭解 Javascript 的人而言,學習 Lua 是很是簡單的,由於Lua 和 Javascript 有不少的共同點。在學習的過程當中,咱們能夠經過這些共同點很快的熟悉 Lua,但須要注意二者間一些關鍵性的不一樣的地方。html
經過 Javascript 的相關知識學習 Lua 的系列總共三篇,這是其中的第一篇。這篇文章中包含一些基礎概念:安裝 Lua,變量,數據類型,操做符和表達式。第二篇將會涉及流程控制和數據結構,第三篇講解對象相關的一些知識。java
文章中出現的 Javascript 代碼大多都遵循 2009 年制定的 EACMScript 5 標準,也就是 ES5 標準。如今最新的 Javascript 標準的是 ES6 或者稱爲 ES2015。我會用到一些 ES6 的語法,並指出這是 ES6 的特性,這樣讀者就能知道這段 Javascript 代碼遵循的標準。不過讀者並不須要瞭解 ES6,我也不會對用到的 ES6 特性進行解釋。node
官方安裝指南傳送門。
若是在 Mac 上安裝了 homebrew,運行 brew install lua
。ubuntu 的話,運行 sudo apt-get install lua5.2
,若是從源碼編譯安裝能夠安裝最新的版本的 Lua。在 windows 上請使用 LuaDist 安裝。linux
在 Max OSX 和 Linux 上經過編譯源碼的方式安裝 Lua 很簡單,執行下面的 shell 命令。若是是 Max OS X,把最後一行的 linux 替換爲 macosx 。shell
curl -R -O http://www.lua.org/ftp/lua-5.3.3.tar.gz
tar zxf lua-5.3.3.tar.gz
cd lua-5.3.3 make linux test # Mac 的話把 linux 替換爲 macosx.
安裝完成後,就可使用 lua 命令了,運行 lua 應該看到如下輸出。macos
$ lua
Lua 5.3.3 Copyright (C) 1994-2016 Lua.org, PUC-Rio >
任意一個文本編輯器都能用來寫 Lua 腳本,寫一段代碼保存爲 my_file.lua,執行 Lua 腳本相似 node.js 執行 Javascript 腳本,使用命令就行了。ubuntu
lua my_file.lua
Lua 中的多行註釋的以 --[[
開始,以 ]]
結尾。 若是 --
以後沒有 [[
,那麼這行是一個單行註釋。例如:
print('Why, hello!') -- print 方法輸出一段字符串 --[[ 這裏是一個 多行註釋!]]
Lua 會忽略縮進。通常的空格也會被忽略,可是會保留字符串的空格和單行註釋後面的空白行。行尾的分號可寫可不寫,通常而言不用寫。
和 Javascript 同樣, Lua 的變量是動態類型的,也使用垃圾回收器管理內存。多數的 Lua 變量類型都能在 Javascript 中找對應的類型。
Javascript 變量類型 | Lua 變量類型 | Lua 變量例子 |
---|---|---|
boolean | boolean | true or false |
null or undefined | nil | nil |
number | number | 3.141 |
string | string | 'hi' or "there" |
object or array | table | {a=1, [2]=false} |
function | function | function() return 42 end |
symbol(ES6) | unique tables | 'hi' or "there" |
It's handy to classify boolean values in term of falsiness; a value is called falsy when it evaluates to false to a boolean context; Lua 中僅有的假值是 nil 和 false。相似地在 Javascript 中,0
,''
和 undefined
都是假值。
Lua 的 numbers
類型,因爲歷史緣由,使用了浮點數來表示——就像 Javascript 的 numbers
。從 Lua 5.3 開始,Lua 增長了對整數類型的支持,increasing the range of integral values that can be represented exactly.
直觀的來看,若是 Lua 的 number
類型變量被初始化爲整數,它被看成一個整數,而且會一直保留整數形式直到遇到可將它變爲非整數的操做,好比除法。下面的代碼展現了 Lua 如何處計算數學表達式——有些運算獲得整數,有些獲得浮點數。
-- Lua
n = 100
print(n) --> 100; 使用整數形式存儲 print(n * 2) --> 200; 運算結果是整數 print(n / 2) --> 50.0; 運算結果是浮點數
相似 Javascript 中的 objects
,Lua 的 table
類型是一個全能的數據結構。
table
能夠被用作哈希表或者是數組。不過 Javascript 中 object
的 keys 只能是字符類型,Lua table
的 keys 能夠是任何的非 nil
值。在 Lua 中 只有兩個 table 是同一個對象時纔會相等,而不是它們擁有相同的內容。
-- Lua
myTable = {}
print(myTable == myTable) --> true print(myTable == {}) --> false
Lua 中 function 是一等公民——能夠建立匿名函數,把函數賦值給變量,也能夠把函數看成另外一個函數的參數或者返回值。若是在函數中引用了定義在該函數做用域以外的自由變量,將隱式地造成一個閉包(譯者注:和 Javascript 中的閉包很相似)。同時 Lua 中的函數支持高效的尾遞歸,也就是在函數的結尾調用另外一個函數,調用棧不會增長。
Lua 中還有兩個類型 userdata 和 thread。userdata 是使用 Lua 的 C 語言 API 調用 C 語言生成的對象。userdata 就像一個擁有私有數據的 table,也能夠自定義它的行爲。 Lua 的 thread 是一個 coroutine,容許函數使用 yield 一些值並保持自身的棧和內部狀態。
Lua 中變量的做用域默認是全局做用域。Lua 的 local
關鍵字有點像 Javascript 中的 var
,只不過 Lua 中沒有聲明提高。也就是說,Lua 中的 local
和 ES6 中的 let
同樣,都是塊級做用域。
-- Lua
phi = 1.618034 -- `phi` 是全局變量。 local gamma = 0.577216 -- `gamma` 只在當前的塊做用域下可見。
Lua 中沒有常量或者私有變量。不過能夠像 Javascript 中同樣,使用閉包來模擬私有變量。建立一個函數,在函數中引用定義在函數以外的變量,這就使得這些變量在函數以外不可見,達到相似私有變量的效果。 Lua 的函數相關內容將在下一篇文章中涉及。
Lua 和 Javascript 中的數學運算,像是加法和乘法,基本上是同樣的。二者都提供了獲取餘數的操做%
,不一樣的是: Javascript 中的 %
在左側操做數是負數時會返回負值,而 Lua 中的 %
老是返回非負值。Lua 中可使用 ^ 進行指數操做。
-- Lua
print(2 ^ 10) --> 1024.0 print(-2 % 7) --> 5
Javascript 不支持操做符重載,可是 Lua 支持。Lua 經過一種稱爲 metamethods(修改元數據) 特殊函數實現的重載,這部份內容將會在最後一篇文章中解釋。Javascript 有一個三元操做符,但 Lua 中並無,不過在 Lua 中能實現相似的效果,這須要藉助 Lua 中的短路操做符 or 和 and。
-- Lua
-- Lua 中模擬三元操做符.
local x = myBoolean and valueOnTrue or valueOnFalse -- 例子:找到 a 和 b 的中的最大值. local maxNum = (a > b) and a or b -- 相似 Javascript 中的如下代碼 -- var maxNum = (a > b) ? a : b;
這個實現頗有效除非 valueOnTrue 是假值。大部分狀況下都不會有問題由於 Lua 的數字,字符和表不會被看成假值。
在 Javascript 中被普遍認同的的一個最佳實踐是使用 ==
而不是 ==
,由於 Javascript 中的 ==
引起使人疑惑的隱式的類型轉換。對於 ===
, Javascript 只有當比較的值有相同的類型的時候纔會返回 true
。
Lua 只有 ==
一種比較操做符,和 Javascript 中的 ===
同樣要求類型相同。如下的例子使用了 Lua 中的內置函數 tonumber
,它將一個字符串轉化爲數字。
-- Lua
print(6.0 * 7.0 == '42') --> false, 不一樣的類型 print(6.0 * 7.0 == tonumber('42')) --> true, 都是 number 類型
Lua 的 <
和 >
操做符在比較的值是不一樣的類型時將會獲得 false
。它們比較字符使用字符標排序,比較數字使用數字排序。
Lua 5.3 引入了內置的位操做符,見下表。表中的操做符在 Lua 和 Javascript 中均可用。
操做符 | 含義 |
---|---|
& | 與 |
Ι | 或 |
~ | 取反 |
<< | 左移 |
Lua 中的~
,就像 Javascript 中的 ^。
-- Lua
print(6 & 18) --> 2; 00110b AND 10010b = 00010b. print(6 | 18) --> 22; 00110b OR 10010b = 10110b. print(6 ~ 18) --> 20; 00110b XOR 10010b = 10100b.
Javascript 中區分了 >> 和 >>> 操做符, >> 保持符號而 >>> 使用 0 填充。Lua 中的 >> 就像 Javascript 中的 >>> 的操做符,使用 0 來填充空位。
這篇文章包含了一下基礎知識,運行 Lua並理解 Lua 中的數據類型和表達式。下一篇文章將會包含更多的內容,好比Lua 的流程控制關鍵字,函數和很重要的 table。