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")
endlocal function func2()
print("這是一個私有函數!")
endfunction module.func3()
func2()
endreturn 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)) -- deadprint("----------")
-- 作用與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) --3print(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