iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 6
0
Software Development

30天 Lua重拾筆記系列 第 6

【30天Lua重拾筆記06】基礎1: 變數

  • 分享至 

  • xImage
  •  

本文同步發表於個人網站

變數名稱

Lua的變數名稱可以是底線(_)或是任意字母([a-zA-Z])開頭,不能是數字或其他字元。之後的組成可以包含數字([0-9])、字母([a-zA-Z])或底線,並且是大小寫敏感,abcAbcABC可以作為三個不同的變數。

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的基本型別有:

  1. nil
  2. boolean
  3. number
  4. string
  5. function
  6. userdata
  7. thread
  8. table

在接著幾天會先介紹幾個經常使用的。

變數預設值

使用為宣告的變數並不會出錯,只會得到nil。參考:基礎1: 類型-nil

變數屬性

Local variables Attribute是Lua 5.4後新加入的特性。其可以針對局部變數賦予一些特定行為。當前Lua 5.4支援兩種屬性--constclose。來看點例子:

固定變數

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

上一篇
【30天Lua重拾筆記05】基礎1: 程式區塊(block、chunk)、排版
下一篇
【30天Lua重拾筆記07】基礎1: 類型-數字
系列文
30天 Lua重拾筆記36
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言