1. 程式人生 > >lua學習之基礎概念篇

lua學習之基礎概念篇

基礎概念

程式塊 (chunk)

定義

  1. lua 中的每一個原始碼檔案或在互動模式(Cmd)中輸入的一行程式碼都稱之為程式塊
  2. 一個程式塊就是一連串語句或者命令
  3. lua 中連續的語句不需要分隔符,但為了可讀性可以加換行,或者分隔符分號 ; 來分割語句
  4. 但是換行在程式碼中沒有任何作用,僅僅是為了提高可讀性
a = 1
b = a * 2

a = 1;
b = a * 2

a = 1; b = a * 2
a = 1 b = a * 2

一個程式塊可以僅包含一條語句,也可以由多條不同的語句或函式的定義構成

  1. 程式塊可以是任意大小的
  2. 可以將程式塊儲存在檔案中然後再執行
  3. 也可以將程式塊放到互動模式中執行直譯器

當不使用任何引數直接執行直譯器時會看到這樣得提示符

Lua 5.1.5 Copyright (C) 1994-2012 Lua.org Puc-Rio
>
  1. 在這種模式下輸入得每條命令都將立即被執行
  2. 要退出互動模式和直譯器
    1. 可以呼叫作業系統庫的 exit 函式,輸入 os.exit()
    2. 或者 end-of-file 控制字元,在 DOS/Windows 中是 Ctrl + Z
  3. 在互動模式中直譯器通常將所輸入的內容當作一個完整的程式塊來解釋
  4. 如果直譯器檢測到某行所輸入的內容不足以構成一個完整的程式塊,那麼它就會等待輸入
  5. 這種機制的存在使得我們可以在互動模式中輸入某些函式的多行定義

但將多行內容放入檔案中才是更常見的做法

  1. 在互動模式中通過呼叫直譯器來執行檔案
-- fact.lua 階乘檔案
function fact(n)
    if n == 0 then
        return 1  --0的階乘是1
    else 
        return n * fact(n - 1)  --輸入3會執行 3 * 2 * 1
    end
end
print("Enter a number:")
a = io.read("*number")
print(fact(a))

-i 引數

  1. 通過 -i 引數來啟動直譯器
  2. lua -i prog
  3. 這樣會先執行檔案 prog 中的程式塊後再進入互動模式

讀取使用者輸入並指定格式

  1. io.read("*number") 讀取數字格式

dofile 函式

  1. 立即執行一個函式檔案
  2. 執行後如果無報錯
  3. 相當於載入了這個lua 檔案中的函式庫
  4. 就可以在後續的互動模式中直接呼叫這個函式庫裡定義的方法
  5. 方便測試新的程式碼,在程式碼編輯器中修改後在互動模式中執行dofile即載入修改後新的程式碼
  6. 使用 dofile 后里面字串檔案路徑的  記得再用一次  進行轉義
  7. 如:dofile("d:\\demo\\a.lua")
-- lib1.lua
-- 計算兩個數的平方和在開平方根
function norm(x, y)
    return (x ^ 2 + y ^ 2) ^ 0.5
end
-- 計算某數的兩倍
function twice(n)
    return n * 2
end
> dofile("lib1.lua") -- 載入你編寫的程式庫,需要填完整的檔案路徑
> n = norm(3.14, 1.0) -- 3.2953907203851
> print(twice(4)) -- 8

詞法規範

識別符號

  1. 可以由任意字母、下劃線、數字構成的字串
  2. 但不可以由數字開頭

避免使用以一個下劃線開頭之後跟著一個或多個大寫字母的識別符號

  1. lua 會將這些識別符號保留,用作特殊用途
  2. 如 _VERSION, _PROMPT
  3. 因為這是 lua 中的啞變數

區域設定(Locale)

  1. 在 lua 中什麼是字母的概念依賴於區域設定(Locale)
  2. 如果設定了對應的區域如希臘,就可以使用希臘字母作為變數名了
  3. 但這樣的變數可能無法在不支援該區域的系統上執行

保留字

  1. and
  2. break
  3. do
  4. else
  5. elseif
  6. end
  7. false
  8. for
  9. function
  10. id
  11. in
  12. local
  13. nil
  14. not
  15. or
  16. repeat
  17. return
  18. then
  19. true
  20. until
  21. while

lua中區分大小寫,如 "And" "AND" 是可以作為變數的,且與保留字 and 完全不同

註釋的寫法

  1. 單行註釋:--code block
  2. 多行註釋:--[[ code block ]]
  3. 一旦寫了註釋後面的程式碼將不會起作用,直譯器會將其忽略
  4. 小技巧:建議這樣寫多行註釋 --[[ code block --]]
  5. 可以在塊註釋前加一個連字元 - 即可啟用程式碼塊中的程式碼
--[[
    print(222)
    print(666) --都不起作用(因為塊註釋註釋掉了其中的程式碼)
--]]

-- 常規寫法加一個連字元寫塊註釋
---[[
    print(222)
    print(666) --會報錯
]]

-- 推薦寫法加一個連字元寫塊註釋
-- 因為這樣寫的話,第一行和最後一行就變成了兩個彼此獨立的單行註釋
---[[
    print(222)
    print(666)
--]]

-- 在註釋塊中包含註釋,在不加 = 的時候會報錯
-- 可以在註釋 --[任意個=[]]與之前匹配的任意等號]

--[==[
    --[[
        print("在多行註釋中輸入多行註釋")
    --]]
    -- print("在多行註釋中輸入單行註釋")
--]==]

全域性變數

  1. 全域性變數不需要宣告
  2. 只需要將一個值賦給這個全域性變數即可建立
  3. 在 lua 中訪問一個未初始化的變數並不會發生錯誤
  4. 但訪問的結果是一個特殊的值 nil ,也就是空值
  5. 刪除全域性變數,將它賦值為 nil
print(b) -- nil
b = 10
print(b) -- 10

-- 刪除全域性變數
b = nil 
print(b) -- nil

直譯器程式

  1. [] 代表可選項
  2. lua [選項引數] [指令碼[引數]]
  3. 不使用引數會直接進入互動模式
  4. -e 直接在命令列中輸入程式碼
  5. 如果只有 -e ,沒有 -i 那麼就不會進入互動模式,而是執行後直接結束
  6. -l 用於載入庫檔案

_PROMPT

  1. 修改這個全域性變數,就會修改互動模式下的命令提示符
  2. 外面的雙引號用於阻止 shell 誤解內層的單引號
lua -i -e "_PROMPT = 'lua>'"
Lua 5.1.5  Copyright (C) 1994-2012 Lua.org, PUC-Rio
lua>

在互動模式中列印任何表示式的值

  1. print()
  2. 也可以使用等號開頭後面跟一個表示式 =

在直譯器執行其引數前

  1. 先會尋找一個 LUA_INIT 的環境變數
  2. 如果找到了,並且它的內容為 @檔名 的話
  3. 直譯器就會先執行這個檔案
  4. 如果 LUA_INIT 沒有以 @ 開頭,直譯器就假設變數內容為 lua 程式碼,並執行這段 lua 程式碼
  5. LUA_INIT 可以靈活地配置直譯器,並且可以完全控制如何配置它
  6. 比如:可以預先載入一個程式包(Package)、修改命令提示符和路徑、定義函式、對函式進行改名或刪除等。

執行指令碼前的引數

  1. 在指令碼程式碼中,可以通過全域性變數 arg 來檢索指令碼的啟動引數
  2. 直譯器在執行指令碼前,會用所有的命令列引數建立一個名為 arg 的 table
  3. 指令碼名稱位於索引 0 上
  4. 它的第一個引數(示例中的 a) 位於索引1 ,以此類推
  5. 而在 指令碼檔案(示例中的 script ) 之前的的所有選項引數位於負數索引上
lua 指令碼 a b c
lua -e "sin = math.sin" script a b 
-- 直譯器將所有引數組織排列為:
arg[-3] = "lua"
arg[-2] = "-e"
arg[-1] = "sin = math.sin"
arg[0] = "script"
arg[1] = "a"
arg[2] = "b"
  1. 通常指令碼只會使用正數索引(示例中的 arg[1] 和 arg[2])
  2. 在 lua 5.1 中,一個指令碼還可以通過 “變長引數語法” 來檢索其引數
  3. 在指令碼主體中,表示式 "..." 3個點表示所有傳遞給指令碼的引數

心得體會

第一日複習

  1. local 區域性變數使用
  2. return 用於返回
  3. if, elseif, then, end, 用於條件判斷程式結構
  4. for, while, then, end 用於迴圈程式結果
  5. and, not, or 用於邏輯判斷
  6. function 用於定義函式
  7. true false 用於條件值的判斷
  8. nil 用於將全域性變數、table中的元素銷燬,也是變數在未賦值之前的預設值

沒有熟練掌握的保留字

  1. break
  2. true
  3. false
  4. in
  5. local
  6. nil
  7. not
  8. return
  9. while

第二日複習

流程控制保留字

  1. if
  2. then
  3. end
  4. elseif
  5. for
  6. do
  7. while
  8. until
  9. repeat
  10. break

條件判斷保留字

  1. true
  2. false

邏輯判斷保留字

  1. and
  2. or
  3. not

其他保留字

  1. in
  2. return 返回
  3. function 函式

沒記住的保留字

  1. id
  2. nil 表示為空,用於清除變數、table元素
  3. local 區域性變數

在 直譯器執行引數前

概念錯誤,且沒有記住後續步驟

  1. LUA_INIT的變數
  2. 找到了 @檔名
  3. 沒找到

在 lua 執行指令碼前的引數

沒有記住所有的內容和概念

程式塊、互動模式、直譯器

記憶的概念沒有匹配對應名稱,記憶混亂的情況

第三日複習

流程控制保留字

if, elseif, then ,end, break, for, do, return, while, until, repeat

型別保留字

nil, function, local

其他

in, id

邏輯判斷

and, or, not

條件判斷

true, false

在直譯器執行引數前

  1. 會先尋找一個名為 LUA_INIT 的環境變數
  2. 找到了並且內容為 @檔名,就會執行這個檔案
  3. 沒找到,就執行直譯器中輸入的內容 【錯誤】
    沒找到,就假設這個變數為 lua 程式碼,並執行

第三步記憶和理解出錯

執行指令碼前的引數

  1. 會建立一個名為 arg 的 table 把這些引數全部存進去
  2. 指令碼名 為索引 0, 其後的引數以此類推
  3. 指令碼名前的引數為負數
  4. 一般不會使用負數索引
  5. 可變長度引數 ... 【記憶混亂】

需要記憶的點

  1. 【全域性變數 arg】 檢索啟動引數
  2. ... 表示所有傳遞給指令碼的引數

  3. 指令碼可通過變長引數語法來檢索引數

  4. 全域性變數的建立概念和宣告