本文同步發表於個人網站
Lua的變數名稱可以是底線(_
)或是任意字母([a-zA-Z]
)開頭,不能是數字或其他字元。之後的組成可以包含數字([0-9]
)、字母([a-zA-Z]
)或底線,並且是大小寫敏感,abc
、Abc
、ABC
可以作為三個不同的變數。
Lua作為嵌入型語言,使用最基本的ascii code。儘管其本帶有utf8函式庫,也可能有部份實現允許其他字元作為變數名稱,但不建議這樣做,並且在使用到非ascii字元時,最好以\u{1F603}
這樣方式來寫。像是:
print("\u{1F603}")
print('?')
上面兩著等價,或是下面兩者亦相同。
print("\u{4f60}\u{597d}\u{ff0c}\u{4e16}\u{754c}\u{ff01}")
print("你好,世界!")
當然其實Lua是了解utf-8的,本系列也不會以上述方式撰寫,所以請確定儲存的程式檔案是以utf-8儲存,否則執行結果可能不如預期。
此外,Lua的底線開頭的變數,和Python一樣有時也代表一些意義,這會在說道metatable和物件導向程式設計時說明。
與多數程式語言一樣,分有全局變數和局部變數。不同的是,預設變數可見範圍是全局的(類似JS的var變數)。
g1 = 1
function f()
print(g1)
g2 = 2
end
f()
print(g2)
1
2
上例中執行完f()
,後g2
便於全局可見。如果要宣告局部變,需要加上local
關鍵字:
g1 = 1
function f2()
print(g1)
local g2 = 2
end
f2()
print(g2)
1
nil
局部變數是區塊變數,關於區塊請參考:基礎1: 程式區塊(block、chunk)、排版。
作為動態弱型別的程式語言,變數是沒有型別的,值才有型別。Lua的基本型別有:
nil
boolean
number
string
function
userdata
thread
table
在接著幾天會先介紹幾個經常使用的。
使用為宣告的變數並不會出錯,只會得到nil
。參考:基礎1: 類型-nil
Local variables Attribute是Lua 5.4後新加入的特性。其可以針對局部變數賦予一些特定行為。當前Lua 5.4支援兩種屬性--const
和close
。來看點例子:
do
local PI <const> = math.pi
print(PI)
PI = 3.14 -- try to change const PI, raise error
end
attempt to assign to const variable 'PI'
上述嘗試將固定變數重新賦值,而會引發錯誤。不過Lua的固定變數與C/C++不同,比較像是JS或著C/C++概念裡的指針。
do
local obj <const> = {}
obj.name = "An Object"
obj.fun = function() return "Obj Function" end
print(string.format([[Show Obj Attribute
------------
Obj Name: %s
Call Obj.fun Result: %s
]], obj.name, obj.fun()))
end
Show Obj Attribute
------------
Obj Name: An Object
Call Obj.fun Result: Obj Function
雖然無法重新賦予變數obj
值,但其fields是可以被改變的,這點與JS相同。
在之後提到metatable
時,可能會提到__close()
方法。之後會在說明,但簡單說,擁有close
屬性的局部變數,在離開局部區塊前,會自動調用__close()
方法。
在宣告為close
變數後,必須給予一個可關閉的值。雖然預計本系列不怎麼會討論檔案,但這邊有必要稍微提一下。
Lua開啟檔案可以使用io
函式庫。
io = require "io"
f = io.open("text.txt", "w")
print(f) -- => file
f:close()
print(f) -- => file (closed)
檔案(file
)是具有close
方法的。不過這還不夠,實際上上面幾乎相同於下面:
io = require "io"
f = io.open("text.txt", "w")
print(f) -- => file
getmetatable(f).__close(f)
print(f) -- => file (closed)
因為下面成立,才可以使用close
變數
f = io.open("text.txt", "w")
do
local _f <close> = f
print(f) -- file f still open
end
print(f) -- file f is closed
這個寫法是為了顯示檔案已經被關閉,更好的寫法如下:
do
local f<close> = io.open("text.txt", "w")
-- do some thing with f
end
這就有點像是Python的with
語句
with open("text.txt", "w") as f:
# do something with file f
pass
附帶一題,file
是個大概不會提到的資料型態--userdata
。
do
local f <close> = io.open("text.txt",'w')
print(type(f)) -- Output: userdata
end