第52天-lua语言基础语法
Sublime 編輯器
注意:在保存lua文件時,必須是<文件名.lua>的形式,必須加.lua后綴名
執(zhí)行腳本:Ctrl + B
清空執(zhí)行結果區(qū):全選 + 刪除
Lua語句
Lua語言是區(qū)分大小寫的
Lua語句不需要使用分號結尾, 但是即使寫了分號也不保錯
Lua注釋
單行注釋:-- (sublime快捷鍵:ctrl+/)
多行注釋:--[[ 語句 ]] (sublime快捷鍵:ctrl+shift+/)、--[[ 語句 ]]--、--[[ 語句 --]]
--單行注釋
--print("11111111111")
--多行注釋
--[[
print("22222222222")
print("33333333333333")
]]
--[[
print("22222222222")
print("33333333333333")
]]--
--[[
print("22222222222")
print("33333333333333")
--]]
多行注釋推薦使用--[=[注釋內(nèi)容]=]
print("44444444444444444")
Lua變量定義
變量名 = 初始值
無需指定數(shù)據(jù)類型, 會根據(jù)賦值的值自動改變變量的數(shù)據(jù)類型
-- C# 數(shù)據(jù)類型 變量名 = 初始值 c1 = [[abcdefg]] print(c1, type(c1))
變量名(標識符)規(guī)范
1、以字母或下劃線開頭
2、后面可以有數(shù)字、字母、下劃線組成
3、盡量避免 下劃線+大寫字母 開頭的寫法,lua自身保留格式
查看變量類型
type(變量名)
num = 10.1 print(num, type(num))
Lua數(shù)據(jù)類型
number數(shù)字類型
lua不區(qū)分整數(shù)與小數(shù), 數(shù)都是number類型
num = 10.1 print(num, type(num)) num2 = 10 print(num2, type(num2))
nil空數(shù)據(jù)
等同于null
nil可以使用在條件判斷中,表示false結果
boolean布爾類型
ture 或者 false
lua認為只有false和nil是假的(不滿足條件), 其他都是真的(滿足條件)
string字符串類型
Lua沒有字符類型, 雙引號與單引號都表示字符串類型
"字符內(nèi)容":不可以換行編輯
'字符串內(nèi)容':不可以換行編輯
[[字符串內(nèi)容]]:可以換行編輯,容易與多行注釋沖突
字符串的基本操作
數(shù)學運算符 +、-、*、/、%
當兩個字符串進行數(shù)學運算符運算時,會將兩個字符串轉換成數(shù)值進行計算,如果轉換失敗就報錯
str1 = "5"
str2 = "7"
print("--------------------------字符的數(shù)學運算------------------------------")
str3 = str1 + str2
str4 = str1 - str2
str5 = str1 * str2
str6 = str1 / str2
str7 = str1 % str2
print(str3)
print(str4)
print(str5)
print(str6)
print(str7)
字符串的連接
使用“..” 兩個點進行拼接
print("-----------------------------字符串的連接-----------------------------")
str8 = str1 .. str2
print(str8)
字符串的長度
#變量名
print("----------------------字符串的長度------------------------")
str9 = "12345asgfasfd"
length = #str9
print(length)
str10 = [[12345a
sgfasfd]]
length = #str10
print(length)
Lua運算符
算術運算符
+, -, *, /, %
print(1 + 2) print(4 % 2)
^:冪次方
2 ^ 3表示2的3次方
print(2 ^ 3)
關系運算符
<,>,<=,>=,==,
print(1 > 2)
~=:不等判斷,與C#不一樣
print(1 ~= 2)
邏輯運算符
and:與
同時為真才為真,相當于C# &&
print(true and true) print(false and true)
or:或
只要有一個為真就為真,相當于C# ||
print(false or true)
not:非
取反,相當于C# !
print(not true)
流程控制語句
if 條件 then 語句 end
--num為nil, lua認為nil為false
if not num then
print("num為nil")
end
year = 2004
--1 能被4整除,不能被100整除
--2 能被400整除
if (year % 4 == 0 and year % 100 ~= 0) or year % 400 == 0 then
print("year: "..year.." 是閏年")
end
if 條件 then 語句1 else 語句2 end
-- if else
age = 19
if age > 18 then
print("你已經(jīng)成年了")
else
print("你未成年")
end
if 條件1 then 語句1 elseif 條件2 then 語句2 else 語句3 end
-- if else if else
--判斷字符串是否是A或B ,如果是A打印 A1,如果是B打印B2, 如果都不是,打印C3
str = "9"
if str == "A" then
print("A1")
--elseif是放在一起寫的,中間沒有空格, 只要是條件判斷,條件后要加then關鍵字
elseif str == "B" then
print("B2")
else
print("C3")
end
循環(huán)語句
while
--[[
C# :
while(循環(huán)條件)
{
循環(huán)體
}
]]
--[[
Lua:
while 循環(huán)條件 do
循環(huán)體
end
]]
num = 37
--判斷num是否是質(zhì)數(shù), 只能被1和本身整除的數(shù)就是質(zhì)數(shù)
print("判斷num是否是質(zhì)數(shù), 只能被1和本身整除的數(shù)就是質(zhì)數(shù)")
isPrime = true
i = 2
while i < num do
if num % i == 0 then
isPrime = false
--可以跳出
break
end
i = i + 1
end
if isPrime then
print("num: "..num .."是質(zhì)數(shù)")
else
print("num: "..num .. "不是質(zhì)數(shù)")
end
--打印100到999之間的水仙花數(shù)
--153 = 1*1*1 + 5*5*5 + 3*3*3
print("打印100到999之間的水仙花數(shù)")
num = 100
while num < 1000 do
--取個位,十位,百位
one = num % 10;
tow = (num - one) / 10 % 10
-- (153 - 3 - 5 * 10) / 100
three = (num - one - tow * 10) / 100
if one^3 + tow^3 + three^3 == num then
print(num)
end
num = num + 1
end
repeat
--[[
C#:
do
{
循環(huán)體
}while(循環(huán)條件)
滿足條件循環(huán)
]]
--[[
lua:
repeat
循環(huán)體
until 跳出循環(huán)條件
滿足條件退出循環(huán)
]]
num = 10
repeat
print(num)
num = num - 1
--注意條件是跳出循環(huán)的條件
until num >= 1
for
--[[
C#
for(int 變量 = 初始值; 循環(huán)條件; 增量表達式)
{
循環(huán)體
}
]]
--[[
Lua
for 變量 = 初始值, 閾值, 增量值 do
循環(huán)體
end
變量超過閾值,結束循環(huán),
每次循環(huán)變量都增加增量值
增量值可以省略,如果省略那么默認是1
]]
--打印2到100之間的質(zhì)數(shù),包含2和100
for num = 2,100 do
isPrime = true
for i = 2, num-1 do
if num % i == 0 then
isPrime = false
end
end
if isPrime then
print(num)
end
end
--打印2000年到2050年之間的所有閏年
for year = 2000, 2050 do
if (year % 4 == 0 and year % 100 ~= 0) or year % 400 == 0 then
print(year)
end
end
注意:lua的循環(huán)語言可以使用break跳出,但是沒有continue
Lua中的數(shù)組
lua 中沒有數(shù)組的,是使用表table結構來模擬數(shù)組, 長度不是固定的
lua數(shù)組的默認索引是從1開始的,不是從0,遇到非連續(xù)的索引后就停
--[[
C#
數(shù)據(jù)類型[] 數(shù)組名 = new 數(shù)據(jù)類型[數(shù)組的長度]
]]
--[[
lua 中沒有數(shù)組的,是使用表table結構來模擬數(shù)組, 長度不是固定的
數(shù)據(jù)名 = {}
]]
array1 = {}
--可以初始化賦值
array2 = {"123", "456"}
--打印第1個數(shù)組元素
print(array2[1])
--數(shù)組的長度
print(#array2)
--遍歷數(shù)組
for i = 1, #array2 do
print(array2[i])
end
--對第5個索引賦值為“789”
array2[5] = "789"
--數(shù)組的長度
print("數(shù)組長度: "..#array2)
--這種寫法在語法上沒有錯誤,但是主管不認為是數(shù)組
array3 = {[-1] = "45678", [0] = "123", [1] = "456"}
print(array3[-1])
print(array3[0])
--數(shù)組的長度
print("數(shù)組長度: "..#array3)
--將10 - 1 依次存儲到一個數(shù)組中
arr = {}
index = 1
for num = 10, 1, -1 do
arr[index] = num
index = index + 1
end
for i = 1, #arr do
print(arr[i])
end
函數(shù)
先定義,再執(zhí)行
-- 函數(shù)的定義
--[[
function 函數(shù)名(參數(shù)列表)
end
]]
--[[
函數(shù)名 = function(參數(shù)列表)
end
]]
function Func1()
print("執(zhí)行Func1的方法")
--該位置調(diào)用,只要保證Func1調(diào)用時在Func2定義之后就可以
Func2()
end
--調(diào)用會報錯, 因為Func2在該行執(zhí)行時未定義
--Func2()
Func2 = function()
print("Func2")
end
Func1()
--帶有參數(shù)與返回值的,注意參數(shù)列表無需指定類型
function Func3(a, b)
sum = a + b
return sum
end
sum = Func3(10, 20)
print(sum)
--多個返回值
function Func4()
return 1, "str", true, {"abc", "def"}
end
--接收多個返回值的函數(shù),要使用多個變量接收
one, tow, three, four = Func4()
print(one)
print(tow)
print(three)
print(four[1])
--lua函數(shù)還支持可變參數(shù) ...
function Func5(...)
--通過數(shù)組獲取可變參數(shù)
--[[
args = {...}
for i = 1, #args do
print(args[i])
end
]]
--第二種獲取可變參數(shù)的方式, arg是lua方法中默認的可變參數(shù)組
for i = 1, #arg do
print(arg[i])
end
print("Func5")
end
Func5(1,"334", true, {"abc", "def"})
表(table)
lua中的table是一個關聯(lián)數(shù)組, 索引可以是數(shù)字也可以是字符串
--定義
tab1 = {}
tab2 = {[1] = "123", ["Key"] = 34, Name = "小明"}
--賦值訪問
print(tab2[1])
tab2["Name"] = "小李"
tab2.Name = "小紅"
--訪問字符串索引的元素
print(tab2["Name"])
print(tab2.Name)
print(tab2["Key"])
print(tab2.Key)
-- 釋放
tab2 = nil
print("----------------------------------------------------------")
--表中存儲方法
tab3 =
{
Func1 = function(a)
print("Func1: " .. type(a))
print(a)
end
}
tab3.Func2 = function(a)
print("Func2: " .. type(a))
end
--調(diào)用表中的方法
--當使用:調(diào)用表中初始化時方法或通過表.方法名定義的方法時, 會將表作為第一個參數(shù)傳遞到方法中
--當使用 . 調(diào)用表中初始化時方法或通過表.方法名定義的方法時, 不會將表傳入
tab3:Func1()
print(tab3)
tab3:Func2()
print("=======================================================")
function tab3:Func3(a)
print("Func3: " .. type(a))
print("self: " .. type(self))
end
--當調(diào)用使用 表:方法名 定義的方法時
-- 表.方法()調(diào)用, 表示不傳入當前表
-- 表:方法()調(diào)用, 表示傳入當前表, 不占參數(shù)位置,通過self可以獲取表
tab3:Func3()
模塊化開發(fā)
require 函數(shù)
require("<模塊名>")
TestModel引用其他文件
--執(zhí)行Model.lua的文件
local m = require("Model")
print("-----------------------------------------------------------------")
print(m.Name)
print(m.Age)
m:Show()
print("-----------------------------------------------------------------")
--執(zhí)行Model1.lua的文件, 注意Model1在當前文件文件夾的子文件夾Lesson下
require("Lesson/Model1") -- Lesson/Model1 表示相對路徑,相對于當前文件所在文件夾的路徑
--執(zhí)行文件都有一個加載路徑, 加載路徑都存儲在table表 package.path中
--路徑與路徑間使用分號分隔,后綴是.lua,通過?來匹配文件名
print(type(package.path))
--執(zhí)行Model3.lua的文件, 注意Model3在D盤的TestLua文件夾下
--需要將桌面路徑添加到 package.path 中,文件路徑以 ";" 號分隔,最后的 2 個 ";;" 表示新加的路徑后面加上原來的默認路徑。
package.path = package.path .. ";D:/TestLua/?.lua"
require("Model3")
print("========================================================================")
tab = {"123", "234", "456", "567"}
local Json = require("JsonUtility")
--將表解析成Json串
str = Json.encode(tab)
print(str)
Model
print("Start Model ......")
local Model = {}
Model.Name = "小明"
Model.Age = 18
function Model:Show()
print("我叫:" .. self.Name .. ", 我的年齡: " .. self.Age .. "歲")
end
return Model
元表
算術類
+:__add
--元表, 針對table的, 元表是改變表與表間的運算或操作的規(guī)則的
t1 = {key = "123", age = 18}
t2 = {name = "456", [-1] = "abc", [1] = "ghj", [2] = "fhgdsh", [4] = "asdfasdf"}
add =
{
--合并兩個表為一個新的表
__add = function (tab1, tab2)
local tab = {}
--遍歷tab1
for k,v in pairs(tab1) do
tab[k] = v
end
--遍歷tab2
for k,v in pairs(tab2) do
tab[k] = v
end
return tab
end
}
--設置meta表為t1表的元表
--setmetatable(t1, meta)
setmetatable(t1, add)
--當兩個表向加運算時,先判斷兩個表是否有元表,如果都沒有元表,直接報錯
--如果其中一個有元表,再判斷元表中是否有 __add 的元方法,如果沒有,直接報錯
--如果有元表并且有__add元方法, 那么執(zhí)行__add的元方法, 該方法的返回值就是兩個表相加的結果
--執(zhí)行__add元方法時,將 + 號左邊的表作為第一個參數(shù)傳入, 將+號右邊的表作為第二個參數(shù)傳入
t3 = t1 + t2
--print("t1", t1)
--print("t2", t2)
print(t3)
for k,v in pairs(t3) do
print(k,v)
end
-:__sub
*:__mul
/:__div
比較類
等于:__eq
設置元表
mytable = {} -- 普通表
mymetatable = {} -- 元表
setmetatable(mytable,mymetatable) -- 把 mymetatable 設為 mytable 的元表
__index 元方法
這是 metatable 最常用的鍵。
當你通過鍵來訪問 table 的時候,如果這個鍵沒有值,那么Lua就會尋找該table的metatable(假定有metatable)中的__index 鍵。如果__index包含一個表格,Lua會在表格中查找相應的鍵。
> other = { foo = 3 }
> t = setmetatable({}, { __index = other })
> t.foo
3
> t.bar
nil
如果__index包含一個函數(shù)的話,Lua就會調(diào)用那個函數(shù),table和鍵會作為參數(shù)傳遞給函數(shù)。
__index 元方法查看表中元素是否存在,如果不存在,返回結果為 nil;如果存在則由 __index 返回結果。
mytable = setmetatable({key1 = "value1"}, {
__index = function(mytable, key)
if key == "key2" then
return "metatablevalue"
else
return nil
end
end
})
print(mytable.key1,mytable.key2)
實例輸出結果為:
value1 metatablevalue
__newindex 元方法
__newindex 元方法用來對表更新,__index則用來對表訪問 。
當你給表的一個缺少的索引賦值,解釋器就會查找__newindex 元方法:如果存在則調(diào)用這個函數(shù)而不進行賦值操作。
mymetatable = {}
mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable })
print(mytable.key1)
mytable.newkey = "新值2"
print(mytable.newkey,mymetatable.newkey)
mytable.key1 = "新值1"
print(mytable.key1,mymetatable.key1)
輸出結果為:
value1 nil 新值2 新值1 nil
以上實例中表設置了元方法 __newindex,在對新索引鍵(newkey)賦值時(mytable.newkey = "新值2"),會調(diào)用元方法,而不進行賦值。而如果對已存在的索引鍵(key1),則會進行賦值,而不調(diào)用元方法 __newindex。
總結
以上是生活随笔為你收集整理的第52天-lua语言基础语法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 龙果开源支付系统介绍
- 下一篇: 任正非内部最新讲话:华为要建立高端人才储