Lua 語言學習基礎學習

1、數據類型

 

-- 直接輸出
print("hello")


-- 全局變量
b = 11
print(b)

 

-- nil(空)
print(type(a))
-- 對於全局變量和table,nil 還有清空的作用


-- number(數字)
-- Lua 默認只有一種number類型 -- double(雙精度)


-- string(字符串)
-- 字符串由一對雙引號或單引號來表示
string1 = "this is string1"
string2 = 'this is string2'
-- 在嘗試對一個數字字符串進行算術操作時,Lua會嘗試將數字字符串轉換成數字
print("16" + 6)
-- 字符串連接 ..
print(16 .. 6)
-- 字符串長度 #
print(#string1)


-- table(表)
a = {}
-- 數組的索引可以爲數字或者字符串
a["key"] = "value"
key = 10
a[key] = 22
-- 遍歷
for k,v in pairs(a) do
    print(k .. ":" .. v)
end
-- Lua裏表的初始索引一般以 1 開始,而不是 0
-- table 長度不固定,會自動增加

-- function(函數)
-- 函數名字f,包含一個參數 n
-- 主要實現階乘的計算
function f(n)
    if n==0 then
        return 1
    else
        return n * f(n-1)
    end
end
-- 調用函數
print(f(5))
-- 函數可以存儲在一個變量中
f1 = f
print(f1(5))

-- 匿名函數參數傳遞
-- 函數名 f1,有兩個參數,其中第二個參數爲一個函數
function f1(tab, f2)
    for k, v in pairs(tab) do
        -- 輸出函數返回的值
        print(f2(k, v))
    end
end

-- 新建表
tab = {"a", "b", "c"}
-- 調用函數,匿名函數作爲參數傳入
-- 注意key是從1開始的
f1(tab,
    function(key, val) -- 匿名函數
        return key .. " = " .. val
    end
)


-- 變量
a = 5          -- 全局變量
local b = 10 -- 局部變量
-- Lua可以對多個變量同時賦值
x,y = 11,12
print(x .. "," .. y)
-- 交換x,y的值
x,y = y,x
print(x .. "," .. y)
-- 多值賦值也可用來接收函數返回的多個變量
function f()
    return 11, 12
end
x,y = f()
print(x .. "," .. y)

二、循環

 

-- while 語句
a = 10
-- 從10輸出到20
while(a < 20)
do
    print("a = " .. a)
    a = a + 1
end


-- for 語句
-- 數值for循環
-- 從10變化到1,每次步長爲-1
for i=10, 1, -1 do
    print("i = " .. i)
end
-- 泛型for循環
days = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}
-- i爲數組索引值,v是對應索引的數組元素值,ipairs爲迭代器
for i,v in ipairs(days) do
    print(v)
end


-- repeat...until 語句
-- 循環直到a>15
a = 10
repeat
    print(a)
    a = a + 1
until(a > 15)


-- break 語句
for a = 10,1,-1 do
    print(a)
    if(a < 5)
    then
        break    -- 當a<5,跳出循環
    end
end

三、流程控制

-- if...elseif..else 語句
a = 100
if(a == 10)
then    -- a=10
    print("a 的值爲 10")
elseif(a == 20)
then    -- a=20
    print("a 的值爲 20")
else    -- 沒有匹配。注意不需要then
    print("沒有匹配的值")
end


-- if嵌套語句
a = 100
b = 200
if(a == 100)
then    -- a=100
    if(b == 200)
    then    -- a=100且b=200
        print("a = " .. a .. " b = " .. b)
    end
end

四、函數

-- 多返回值
-- 尋找最大值和最大值所在的位置
function maximum(a)
    local mi = 1        -- 最大值位置
    local m = a[mi]        -- 最大值
    for k,v in ipairs(a) do
        if(v > m) then    -- 更大
            m = v
            mi = k
        end
    end
    return m, mi        -- 輸出最大值及其索引
end

-- 輸出最大值及其索引
print(maximum({8, 10, 13, 6, 15, 9}))

-- 可變參數
-- 求不確定參數個數的平均值
function averge(...)
    result = 0
    -- 可變參數可以賦值給變量
    local arg = {...}
    for k,v in ipairs(arg) do
        result = result + v
    end
    -- #可以獲取...長度
    print("總共傳入 " .. #arg .. " 個數")
    -- 返回平均值
    return result/#arg
end

-- 輸出平均值
print("平均值爲 " .. averge(10, 5, 3, 4, 5, 6))

 

 

 

 

五、運算符

 1 -- 算術運算符
 2 -- + - * / 加減乘除
 3 -- % 取餘 ^ 乘冪 - 負號
 4 
 5 
 6 -- 關係運算符
 7 -- == 等於 ~= 不等於
 8 -- > < >= <= 大於 小於 大於等於 小於等於
 9 
10 
11 -- 邏輯運算符
12 -- and 邏輯與 or 邏輯或 not 非
13 
14 
15 -- 其他運算符
16 -- .. 連接兩個字符串
17 -- # 返回字符串或表的長度

六、字符串

-- 字符串大小寫轉換
s = "Lua"
print(string.upper(s))    -- 大寫
print(string.lower(s))    -- 小寫


-- 字符串查找與反轉
s = "Lua Tutorial"
-- 查找字符串,若查找成功,返回頭和尾,否則返回nil
print(string.find(s, "Tutorial"))
-- 字符串反轉
reverses = string.reverse(s)
print(reverses)


-- 字符串格式化
date = 2
month = 1
year = 2014
-- 日期格式化
print(string.format("%02d/%02d/%04d", date, month, year))
-- 十進制格式化
print(string.format("%.3f", 1/3))


-- 字符與ASCII碼的轉換
-- 轉換第一個字符
print(string.byte("Lua"))
-- 轉換第三個字符
print(string.byte("Lua", 3))
-- 轉換倒數第一個字符
print(string.byte("Lua", -1))
-- ASCII轉字符
print(string.char(97))


-- 字符串長度
s = "Lua Tutorial"
print(string.len(s))


-- 模式匹配
-- 搜索 dd/mm/yy 格式的日期
s = "Deadline is 30/05/1999, firm"
date = "%d%d/%d%d/%d%d%d%d"
print(string.sub(s, string.find(s, date)))
-- 去除空格
-- gsub 返回的第二個參數爲替代字符的個數
print(string.gsub(s, " ", ""))

七、數組

-- 一維數組
array = {}
-- 初始化數組
-- 注意數組下標默認從1開始,但是也可以自定義下標
for i=-2, 2 do
    array[i] = i*2
end
-- 遍歷數組
for i=-2, 2 do
    print(array[i])
end

-- 二維數組
array = {}
maxRow = 3
maxColumn = 3
-- 初始化3行3列數組
for row=1,maxRow do
    array[row] = {}
    for col=1,maxColumn do
        array[row][col] = row * col
    end
end
-- 遍歷數組
for row=1,maxRow do
    for col=1,maxColumn do
        print(array[row][col])
    end
end

八、迭代器

-- pairs和ipairs區別
-- pairs 可以遍歷集合的所有元素,即可以遍歷集合中的所有key
-- ipairs 按照索引升序遍歷,索引中斷停止遍歷
tab = {
[1] = "a",
[2] = "b",
[4] = "c"    -- 注意索引值沒有3
}

-- pairs
-- 輸出 a,b,c
for k, v in pairs(tab) do
    print(v)
end

-- ipairs
-- 只輸出 a,b
for k, v in ipairs(tab) do
    print(v)
end

九、表(table)

-- 初始化表
mytable = {}
-- 指定值
mytable[1] = "Lua"
-- 移除引用
-- 之後Lua垃圾回收會釋放內存
mytable = nil


-- table 連接
fruits = {"banana","orange","apple"}
-- 直接連接
print(table.concat(fruits))
-- 指定連接字符
print(table.concat(fruits, ","))
-- 指定要連接的字符串
print(table.concat(fruits, ", ", 2, 3))


-- 插入和刪除
fruits = {"banana","orange","apple"}
-- 在末尾插入
table.insert(fruits, "watermelon")
print(table.getn(fruits))
-- 在指定位置插入
table.insert(fruits, 2, "pear")
print(fruits[2])
print(table.getn(fruits))
-- 刪除指定位置的元素
print(table.remove(fruits, 4))
print(table.getn(fruits))


-- 排序
fruits = {"banana","orange","apple","grapes"}
print("排序前")
for k,v in ipairs(fruits) do
    print(k,v)
end

-- 排序,默認爲升序
table.sort(fruits)
print("排序後")
for k,v in ipairs(fruits) do
    print(k,v)
end


-- 注意使用 # 和 table.getn 其都會在索引中斷的地方停止計數,
-- 而導致無法正確取得 table 的長度
-- 可以用以下的方法
function table_leng(t)
  local leng=0
  for k, v in pairs(t) do
    leng=leng+1
  end
  return leng
end

十、模塊

  模塊代碼如下:

-- module.lua
-- 定義一個名爲 module 的模塊
module = {}

-- 定義一個常量
module.constant = "這是一個常量"

-- 定義一個函數
function module.func1()
    io.write("這是一個公有函數!\n")
end

local function func2()
    print("這是一個私有函數!")
end

function module.func3()
    func2()
end

return module

  調用模塊代碼如下:

-- 加載模塊
-- 返回一個由模塊常量和函數組成的table
 local m = require("module")
 
 print(m.constant)    -- 訪問模塊常量
 m.func3()            -- 訪問模塊函數

十一、協同程序

-- 協同程序
-- 創建協程,resume時喚醒函數
co = coroutine.create(
    function(i)
        print(i);
    end
)

-- 重啓協程,並傳入參數
coroutine.resume(co, 1)   -- 1
-- 輸出協程狀態
print(coroutine.status(co))  -- dead

print("----------")

-- 作用與create一樣
co = coroutine.wrap(
    function(i)
        print(i);
    end
)

co(1)

print("----------")

-- create時就是在新線程中註冊一個事件
co2 = coroutine.create(
    function()
        for i=1,10 do
            print(i)
            if i == 3 then
                print(coroutine.status(co2))  --running
                print(coroutine.running()) --thread:XXXXXX
            end
            -- 遇到yield協程會暫時掛起
            coroutine.yield()
        end
    end
)

-- resume會重新激活事件
coroutine.resume(co2) --1
coroutine.resume(co2) --2
coroutine.resume(co2) --3

print(coroutine.status(co2))   -- suspended
print(coroutine.running())

print("----------")

十二、文件 I/O

-- 文件 I/O
-- 打開文件
file = io.open("協同程序.lua", "r")

-- 輸出文件第一行
print(file:read())

-- 獲取倒數第10個字符位置
file:seek("end",-10)
-- 讀取後10個字符
print(file:read("*a"))

-- 關閉文件
file:close()

-- 以附加的方式打開只寫文件
file = io.open("協同程序.lua", "a")

-- 在文件末尾寫入字符串
file:write("-- test io")

十三、面向對象

 

-- 面向對象
-- Shape 類,包含一個屬性 area
Shape = {area = 0}

-- 構造方法
function Shape:new (o, side)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    side = side or 0
    self.area = side*side
    return o
end

-- 輸出形狀面積
function Shape:printArea()
    print("面積爲:", self.area)
end

-- 創建對象
myShape = Shape:new(nil, 10)
-- 輸出面積
myShape:printArea()        -- 100


-- 繼承
-- 長方形
Rectangle = Shape:new()
-- 派生類構造方法
function Rectangle : new(o, length, breadth)
    o = o or Shape:new(o)
    setmetatable(o, self)
    self.__index = self
    self.area = length * breadth
    return o
end

-- 函數重寫
function Rectangle : printArea()
    print("長方形面積爲:", self.area)
end

-- 創建一個長方形對象
myRectangle = Rectangle:new(nil, 10, 20)
-- 輸出長方形面積
myRectangle:printArea()    -- 200

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章