又LAG隨性筆記
  • 關於我
  • 作品集
  • 生活隨筆
  • 與我聯絡
  • 隨手扎

隨手扎

October 7, 2020

【30天Lua重拾筆記23】中級議題: 閉包

變數的查找

對於一個變數,Lua會先嘗試從當前詞法環境(Lexical)尋找,再從當前環境中尋找(_ENV)。
那的對於區塊變數呢??

function parentFunction()
  local L1 = 100
  local function childFunction()
    print("here is child")
  end
  return childFunction
end

f1 = parentFunction(100)
f1()  -- Output: here is child

上例中,區塊變數L1沒有任何人可以存取的到,簡直消失在了時空夾縫之中。

詞法環境(Lexical)

詞法環境(Lexical)指的是程式編寫當下,執行區塊由內而外,可以見到的範圍。

隱藏區塊變數

在Lua變數預設值為nil。透過查找規則,可以暫時隱藏一切區塊變數。

October 6, 2020

【30天Lua重拾筆記22】中級議題: 全局表(_G)、環境表(_ENV)

_G和_ENV

在Lua有兩個特殊變量–_G和_ENV,其分別表示全局環境和當前環境。_G在與C交互時,另有作用。但大致上你可以將兩者視為相同。實際上,在Lua環境建立之初,兩著也確實是相同的:

print(_G == _ENV) -- => Output: true

先前說過,Lua只有表(table)這個複合結構。而_G和_ENV也是table結構。_ENV中包含一個_G的key,其值指向_G,而起出_G就是_ENV。像是一個咬尾蛇(Ouroboros)

print(_ENV._G == _ENV) -- => Output: true
print(_G == _ENV) -- => Output: true
print(_G._G == _ENV) -- => Output: true
print(_G._G == _G) -- => Output: true

變數查找

對於一個變數,Lua會先嘗試從當前詞法環境(Lexical)尋找,在從當前環境中尋找(_ENV)。這意味著你可以準備一個乾淨的執行環境執行函數。

October 5, 2020

【30天Lua重拾筆記21】基礎3: 再看pairs, ipairs

ipairs()的行為

iparis會嘗試從索引1開始迭代表(陣列),直到其值為nil。所以很像是:

arr = {1,2,3,4,5}

function my_ipairs(t --[[table]])
  local i = 1
  while t[i] ~= nil do
    print(i, t[i])
    i = i + 1
  end
end

my_ipairs(arr)

1 1
2 2
3 3
4 4
5 5


也因此其如果有斷值,會在一半中止:

arr = {1,2,nil, 4, 5}
my_ipairs(arr)

1 1
2 2

pairs()和next()

October 4, 2020

【30天Lua重拾筆記20】基礎3: 複合結構 - table

Lua只有一個原生的複合結構 – table。實際上陣列是table的特例。

陣列是table的特例

arr = {1,2,3,4}
print(type(arr)) --> table

建立表(table)

table對應於:

程式語言型別
pythondict
jsobject or Map

這個結構幾乎是現代高階語言必備的基礎。其又稱作hash-table,是一個鍵值對(key/value)的結構。在Lua之中,其key可以是除了nil和NaN(Not a Number)以外的任何型別。

key值值域

obj = {} -- 建立一個空表
obj[1] = 1 -- 整數是合法的key值
obj[1.0] = 2 -- 浮點數是合法的key值
obj["string"] = 1 -- 字串是合法的key值
obj[math.huge] = 1 -- inf是合法的key值

--[[ 
要注意的是 obj[1] 和 obj[1.0]相同
其obj[1]和obj[1.0]最終值為2
--]]

----------------

print(obj[nil]) --> nil
obj[nil] = 1 --> Error: nil不是合法的key值,儘管取值不會出錯

print(obj[0/0]) --> nil
print(0/0) --> -nan
obj[0/0] = 1 --> Error: NaN不是合法的key值

value值值域

其value可以是nil以外的值。

nil表示該key不存在,亦可視為刪除該key

obj[1] = nil -- 刪除`obj[1]`
print(obj[1]) --> nil --表示obj[1]不存在
October 3, 2020

【30天Lua重拾筆記19】基礎3: 陣列從1開始

建立陣列

關於陣列,其實也已經看過了。不過其實陣列還有兩個祕密,一個今天會揭露,另一個等等明天。

要建立一個陣列很簡單,很像C語言,只是把中括號[]改成大括號{},像是:

programming_language = {
  "C",
  "C#",
  "C++",
  "Java",
  "Swift",
  "Python",
  "Haskell",
}

陣列取值

陣列從1開始

與C語言一樣,使用下標運算取陣列之中的值, 要注意的是,Lua陣列從1開始

print(programming_language[1]) -- => Output: "C"

陣列長度

可以使用長度運算#,取得陣列長度:

print(#programming_language) -- => Output: 7

迭代陣列

知道陣列取值方式,也知道陣列長度後,就可以來迭代陣列:

一般for迴圈方法

for i=1, #programming_language, 1 do
  print(i, #programming_language[i], programming_language[i])
end

看我小巧思,每個值的長度,正好與其對應的索引值相同。

for-in + ipairs() 方法

可以寫的更簡單點:

October 1, 2020

【30天Lua重拾筆記18】基礎2: 應該知道的(總集+補充)

關於變數

  • 值(value)有型別;變數(varible)沒有
  • 基礎型別一共有8個
    1. nil
    2. boolean
    3. number
    4. string
    5. function
    6. userdata
    7. thread
    8. table
  • table是唯一的複合型別(之後會提到)
  • Lua 5.4之後,可以為變數標記屬性。Lua 5.4支援const和close兩種屬性
  • 變數預設是全局變數(實際上與特殊變數_ENV和_G有關,之後會提到)
  • 變數值型別會自動轉型,但不該依賴

數字

  • 整數和浮點數會自動轉換
  • 整數有範圍,有溢位問題
  • 浮點數也有精度丟失的問題

布林

  • 只有nil和false為假,其他為真
  • 0、空字串、空表亦為真

控制結構

  • 有label & goto
  • label只屬於當前函式區塊
  • 使用elseif,而非else if (這點我覺得C就設計的比較漂亮)
    • 嵌套使用if(else if),記得補上end
  • 非強求,但最好做好排版
  • ««
  • «
  • 1
  • 2
  • 3
  •  … 
  • 15
  • 16
  • 17
  •  … 
  • 34
  • »
  • »»
© 又LAG隨性筆記 2025