Lua 基本語法

image.png

概述:

Lua 是一種輕量小巧的腳本語言,用標準 C 語言編寫并以源代碼形式開放,其設(shè)計目的是為了嵌入應用程序中,從而為應用程序提供靈活的擴展和定制功能。

一、變量

Lua 是動態(tài)類型語言,變量不要類型定義。Lua 變量就兩種類型:全局變量、局部變量。
使用 local 關(guān)鍵字聲明的、在函數(shù)體內(nèi)的,就是局部變量。其它都是全局變量。

-- test.lua 文件腳本
a = 5           -- 全局變量
local b = 5     -- 局部變量

function funcationName()
    c = 5       -- 局部變量
    local d = 6 -- 局部變量
end

print(a, b, c, d) -- 打印值為:5 5 nil nil

二、循環(huán)和流程控制語句

2.1、while 循環(huán)
while( true )
do
    print("循環(huán)將永遠執(zhí)行下去")
end

--實例
i = 1
while(i < 5)
do
    i = i + 1
    print(i)
end
2.2、for 循環(huán)

數(shù)值 for 循環(huán):
var 從 exp1 變化到 exp2,每次變化以 exp3 為步長遞增 var,并執(zhí)行一次"執(zhí)行體"。exp3 是可選的,如果不指定,默認為 1。

for var=exp1,exp2,exp3 do  
    <執(zhí)行體>  
end  

--實例
for i=1, 10, 1 do
    print(i)
end

泛型 for 循環(huán):
i 是數(shù)組索引值,v 是對應索引的數(shù)組元素值。ipairs 是 Lua 提供的一個迭代器函數(shù),用來迭代數(shù)組。

--打印數(shù)組 a 的所有值  
for i,v in ipairs(a) 
    do print(v) 
end  ?

--實例
array = {
"value1",
"value2",
"value3"
}

for i,v in ipairs(array) do
    print(i,v)
end
2.3、repeat...until 循環(huán)

repeat...until 循環(huán)和 C 語言里面的 do...while() 作用是一樣的。

repeat
   statements
until( condition )

--實例
i = 1
repeat
    i = i + 1
    print(i)
until(i > 5)
2.4、if 語句

if 語句:

if(布爾表達式)
then
    --[ 在布爾表達式為 true 時執(zhí)行的語句 --]
end

if...else 語句:

if(布爾表達式)
then
   --[ 布爾表達式為 true 時執(zhí)行該語句塊 --]
else
   --[ 布爾表達式為 false 時執(zhí)行該語句塊 --]
end

三、運算符

Lua 提供了以下幾種運算符類型:

  • 算術(shù)運算符
  • 關(guān)系運算符
  • 邏輯運算符
  • 其他運算符
3.1、算術(shù)運算符

算術(shù)運算符就是加法、減法、乘法、乘法、取余等這些。和 C 語言是一樣的。

3.2、關(guān)系運算符

關(guān)系運算 就是等于、不等于、大于、大于等于、小于等于、小于。

3.3、邏輯運算符
  • and 邏輯與操作符。
  • or 邏輯或操作符。
  • not 邏輯非操作符。
a = true
b = true

-- and
if ( a and b )
then
   print("a and b - 條件為 true" )
end

-- or
if ( a or b )
then
   print("a or b - 條件為 true" )
end

-- not
if ( not( a and b) )
then
   print("not( a and b) - 條件為 true" )
else
   print("not( a and b) - 條件為 false" )
end
3.4、其他運算符
  • ..”,連接兩個字符串。

  • #”,一元運算符,返回字符串或表的長度。

  • ~”,相當于 C 中的“!”。

a = "Hello"
b = "World"

if a ~= b  then

end

print("連接字符串 a 和 b ", a..b )

print("b 字符串長度 ", #b )

print("字符串 Test 長度 ", #"Test" )
    
print("Mob 網(wǎng)址長度 ", #"www.mob.com" )

四、基本類型

Lua 中有 8 個基本類型分別為:nil、boolean、 number、string、userdata、function、thread 和 table。

  • nil 類型。表示一個無效值。

  • boolean 類型。false 和 true。

  • number 類型。表示雙精度類型的實浮點數(shù)。

  • string 類型。字符串由一對雙引號或單引號來表示。

  • function 類型。由 C 或 Lua 編寫的函數(shù)。

  • userdata 類型。表示任意存儲在變量中的 C 數(shù)據(jù)結(jié)構(gòu)。

  • thread 類型。表示執(zhí)行的獨立線路,用于執(zhí)行協(xié)同程序。

  • table 類型。Lua 中的表(table)其實是一個“關(guān)聯(lián)數(shù)組”(associative arrays),數(shù)組的索引可以是數(shù)字或者字符串。在 Lua 里,table 的創(chuàng)建是通過“構(gòu)造表達式”來完成,最簡單構(gòu)造表達式是{},用來創(chuàng)建一個空表。

其中 nil、boolean、 number、string 這四種類型和其它語言中的類型的使用都是類似的。 function 和 table 這兩種類型,會在本篇后面部分詳細講解,userdata 和 thread 暫時先不講。

五、table 類型

table 是 Lua 的一種數(shù)據(jù)結(jié)構(gòu)用來幫助我們創(chuàng)建不同的數(shù)據(jù)類型,如:數(shù)組、字典等。

Lua table 使用關(guān)聯(lián)型數(shù)組,你可以用任意類型的值來作數(shù)組的索引,但這個值不能是 nil。

Lua table 是不固定大小的,你可以根據(jù)自己需要進行擴容。

Lua 也是通過 table 來解決模塊(module)、包(package)和對象(Object)的。

5.1、table 的構(gòu)造
-- 創(chuàng)建一個表
mytable = {}

-- table 里面值的設(shè)置和獲取
mytable[1] = "元素1"
mytable["er"] = "元素2"

print("mytable 索引為 1 的元素", mytable[1])
print("mytable 索引為 er 的元素", mytable["er"])
5.2、table 模擬數(shù)組
-- 數(shù)組,lua里面的元素是從 1 開始的
array = {
    "value1",
    "value2",
    "value3"
}

-- 數(shù)組里面值得獲取
print(array[1], array[2], array[3])
5.3、table 模擬字典
-- 字典
dictionary = {
    key1 = "value1",
    key2 = "value2",
    key3 = "value3"
}

-- 字典里面值得獲取
print(dictionary.key1, dictionary.key2, dictionary.key3)

六、函數(shù)類型

函數(shù)是對語句和表達式進行抽象的主要方法。

functionName1 = function(i)
    print(i)
end

function functionName2(i)
    print(i)
end

functionName1(2)
functionName2(2)

和 C 語言相比,Lua 中函數(shù)的幾個不同點:

-- 1、多返回值,多余的返回值會省略,少的補齊 nil
function multreturn()
    return 1, 2
end

print(multreturn())

-- 2、可變參數(shù)
function average(...)
    result = 0
    local arg = {...}
    
    for i,v in ipairs(arg) do
        result = result + v
    end

    print("總共傳入".. #arg.."個數(shù)")
    return result/#arg
end

print("平均值為", average(1, 2, 3, 4, 5, 6, 7, 8, 9))

七、模塊

模塊就是使用 table 來實現(xiàn)的,看起來會讓我們和面向?qū)ο笳Z言里面的類有點相似。

Class = {}

-- 定義一個共有的變量
Class.var1 = "初始化 var1 的值"
-- var1 = "初始化 var1 的值"

-- 定義一個私有變量
local var2 = "初始化 var2 的值"

-- 定義一個共有函數(shù) func1
function Class.func1()
    print("這是共有函數(shù) func1")
end

-- 定義私有函數(shù),該函數(shù)只能在本模塊里面使用
local function func2()
    print("這是私有函數(shù) func2")
end

-- 定義一個全局函數(shù),可以直接其它模塊里面調(diào)用,但是不能通過該模塊去調(diào)用。
function func3()
    print("這是全局函數(shù) func3")
end

return Class

它里面整一個就是一個表,在里面可以定義私有、共有變量,私有、共有函數(shù)。這些特性都是通過表來限制的,如果不是通過表來限制,那這些函數(shù)和變量的作用域都是全局的。

-- 通過require() 函數(shù)導入模塊
local m = require('Module')

print("模塊類型為:", type(m))

-- 修改模塊共有變量
m.var1 = "修改一下 var1"
print("模塊變量值為:", m.var1)

-- 調(diào)用模塊共有函數(shù)
print("模塊func1函數(shù)的調(diào)用:",  m.func1())

-- 模塊的加載過程
print("func3 函數(shù)是不是在這里打???", func3())

八、閉包

閉包是函數(shù)中的函數(shù),可以包含父函數(shù)的局部變量的代碼塊,可以始終讓局部變量的值始終保持在內(nèi)存中。
它的最大用處有兩個,一個是可以讀取函數(shù)內(nèi)部的變量,另一個就是讓這些變量的值始終保持在內(nèi)存中。

-- 示例1
function func1()
    local x = 0
    function ee()
        x = x + 1
        print(x)
    end
    return ee
end

local f1 = func1()
for i=1, 5 do
    f1()
end

-- 示例2
function func2()
    local x = 0
    return function()
        x = x + 1
        print(x)
    end
end

local f2 = func2()
for i=1, 5 do
    f2()
end

-- 示例3
function func3(a)
    local x = a
    return function()
        x = x + 1
        print(x)
    end
end

local f31 = func3(3)
for i=1, 5 do
    f31()
end

local f32 = func3(10)
for i=1, 5 do
    f32()
end

九、元表及元方法

在 Lua table 中我們可以訪問對應的 key 來得到 value 值,但是卻無法對兩個 table 進行操作。
因此 Lua 提供了元表(Metatable),允許我們改變 table 的行為,每個行為關(guān)聯(lián)了對應的元方法。

有兩個很重要的函數(shù)來處理元表:

  • setmetatable(table,metatable): 對指定 table 設(shè)置元表(metatable),如果元表(metatable)中存在 metatable 鍵值,setmetatable 會失敗 。

  • getmetatable(table): 返回對象的元表(metatable)。

-- 給指定表設(shè)置元表
mytable = {}                          -- 普通表 
mymetatable = {}                      -- 元表
setmetatable(mytable, mymetatable)     -- 把 mymetatable 設(shè)為 mytable 的元表 

-- 返回對象元表
getmetatable(mytable)                 -- 這回返回mymetatable
__index 元方法

__index 元方法是 metatable 里面最常見的鍵。

當你通過鍵來訪問 table 的時候,如果這個鍵沒有值,那么 Lua 就會尋找該 table 的 metatable(假定有 metatable)中的 __index 鍵。如果 __index 包含一個表格,Lua 會在表格中查找相應的鍵。

-- 實例1
mytable = {
    key1 = "value1"
}

mymetatable = {
    __index = {
        key2 = "metatablevalue"
    }
}

setmetatable(mytable, mymetatable)

print(mytable.key1, mytable.key2, mytable.key3)


-- 實例2
mytable = {
    key1 = "value1"
}

mymetatable = {
  __index = function(mytable, key)
    if key == "key2" then
      return "metatablevalue"
    else
      return nil
    end
  end
}

setmetatable(mytable, mymetatable)
print(mytable.key1, mytable.key2, mytable.key3)
總結(jié):

Lua 查找一個表元素時的規(guī)則,其實就是如下 3 個步驟:

  1. 在表中查找,如果找到,返回該元素,找不到則繼續(xù)
  • 判斷該表是否有元表,如果沒有元表,返回 nil,有元表則繼續(xù)。

  • 判斷元表有沒有 __index 方法,如果 __index 方法為 nil,則返回 nil;如果__index 方法是一個表,則重復 1、2、3;如果 __index 方法是一個函數(shù),則返回該函數(shù)的返回值。

十、面向?qū)ο笾庋b

面向?qū)ο蟮奶卣饔蟹庋b、繼承、多態(tài)。Lua 是一門弱類型的語言,多態(tài)那肯定是不存在的。
通過元表和元方法以及模塊來模擬類的封裝,請看如下示例:

local User = {}

User.id = 0
User.name = ""
User.age = 0


-- function User:new()
--  print("User 被構(gòu)造了")
--  mytable = {}
--  setmetatable(mytable, self)
--  self.__index = self
--  return mytable
-- end

function User:new(id, name, age)
    print("new self:", self)

    -- print("User 被構(gòu)造了,", id, name, age)
    mytable = {"haha"}
    setmetatable(mytable, self)
    self.__index = self

    self.id = id
    self.name = name
    self.age = age


    return mytable
end

function User:fun()
    -- print("fun 成員方法調(diào)用了")
end

function User:setName(name)
    print("setName self:", self)
    self.name = name
end

function User:getName()
    print("getName self:", self)
    return self.name
end

return User
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • 循環(huán) while for repeat … until 支持 break 流程控制 lua 中 0 為 true,...
    重劍無鋒_Augustine閱讀 851評論 0 0
  • 第一篇 語言 第0章 序言 Lua僅讓你用少量的代碼解決關(guān)鍵問題。 Lua所提供的機制是C不擅長的:高級語言,動態(tài)...
    testfor閱讀 2,936評論 1 7
  • 前言: 在多次地方我看到一個非常好看的線條動畫-波浪。給人很舒服的趕腳,并且也很實用在項目中,比如:下載文件進度,...
    雷晏閱讀 1,895評論 11 26
  • 匆匆那年 今天下午在附近的酒吧聽到了這首歌,想起曾經(jīng)的自己和同桌的故事。 別瞎想,我的同桌z小姐和我一樣,是個女孩...
    羽夏卿塵閱讀 516評論 0 3
  • 文|玫酒 —1— 昨晚和我媽在吃飯時又談到了找對象這個話題,只要在家總是避不開這個。 “你也單身那么長時間了,什么...
    玫酒閱讀 979評論 9 5

友情鏈接更多精彩內(nèi)容