lua基础语法学习
1. 基础
注释
--单行注释
--[[
多行注释
--]]
标识符
标识符以一个字母 A 到 Z 或 a 到 z 或下划线 _ 开头后加上 0 个或多个字母,下划线,数字(0 到 9)。
Lua 不允许使用特殊字符如 @, $, 和 % 来定义标识符。 Lua 是一个区分大小写的编程语言。
关键词
and | break | do | else |
---|---|---|---|
elseif | end | false | for |
function | if | in | local |
nil | not | or | repeat |
return | then | true | until |
while | goto |
其它运算符
操作符 | 描述 | 实例 |
---|---|---|
… | 连接两个字符串 | a…b ,其中 a 为 "Hello " , b 为 “World”, 输出结果为 “Hello World”。 |
# | 一元运算符,返回字符串或表的长度。 | #“Hello” 返回 5 |
数据类型
数据类型 | 描述 |
---|---|
nil | 这个最简单,只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)。 |
boolean | 包含两个值:false和true。lua中数字0是true |
number | 表示双精度类型的实浮点数 |
string | 字符串由一对双引号或单引号来表示 |
function | 由 C 或 Lua 编写的函数 |
userdata | 表示任意存储在变量中的C数据结构 |
thread | 表示执行的独立线路,用于执行协同程序 |
table | Lua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字、字符串或表类型。在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。索引从1 开始 |
Lua 把 false 和 nil 看作是 false,其他的都为 true,数字 0 也是 true
--string
a=[[
<p>表示一块字符串</p>
]]
b="123"
a,b=b,a --交换a,b的值
--table
local tbl2 = {"apple", "pear", "orange", "grape"}
a = {}
a["key"] = "value"
print(a.key) --当索引为字符串类型时可这样用
a[10]=22
for k, v in pairs(a) do
print(k .. " : " .. v)
end
a=nil --移除引用,垃圾回收
--function
function factorial1(n)
local jk=5
print("局部变量jk: "..jk)
if n == 0 then
return 1
else
return n * factorial1(n - 1)
end
end
print(factorial1(5))
factorial2 = factorial1
print(factorial2(5))
--匿名函数
function testFun(tab,fun)
for k ,v in pairs(tab) do
print(fun(k,v));
end
end
tab={key1="val1",key2="val2"};
testFun(tab,
function(key,val)--匿名函数
return key.."="..val;
end
);
2. 输入输出
-- 提示用户输入
print("请输入一些文本:")
-- 读取用户输入的一整行
local userInput = io.read("*line")
-- 输出用户输入的内容
print("您输入的是:" .. userInput)
3. 分支结构与循环结构
if
a = 100
if( a == 10 ) then
print("a 的值为 10" )
elseif( a == 20 ) then
print("a 的值为 20" )
elseif( a == 30 ) then
print("a 的值为 30" )
else
print("没有匹配 a 的值" )
end
print("a 的真实值为: ", a )
for
--[[ 数值for
var 从 exp1 变化到 exp2,每次变化以 exp3 为步长递增 var,并执行一次 "执行体"。
exp3 是可选的,如果不指定,默认为1。
for var=exp1,exp2,exp3 do
<执行体>
end
]]
function f(x)
print("function") ;
return x*2 ;
end
for i=0,f(5),2 do print(i) --f(5)只在开始时执行一次
end
--[[ 泛型for
a = {"one", "two", "three"}
for i, v in ipairs(a) do
print(i, v)
end
]]
repeat…until
--[ 变量定义 --]
a = 10
--[ 执行循环 --]
repeat
print("a的值为:", a)
a = a + 1
until( a > 15 )
while
-- 定义变量
a = 10
-- while 循环
while( a < 20 )
do
print("a 的值为:", a)
a=a+1
if( a > 15)
then
--[ 使用 break 语句终止循环 --]
break
end
end
4. 函数
在函数参数列表中使用三点 ...
表示函数有可变的参数
- select(‘#’, …) 返回可变参数的长度。
- select(n, …) 用于返回从起点 n 开始到结束位置的所有参数列表。
function average(...)
result = 0
local arg={...} -- {...} 表示一个由所有变长参数构成的数组
for i,v in ipairs(arg) do
result = result + v
end
print("总共传入 " .. select("#",...) .. " 个数")
print(select(1,...))
return result/select("#",...)
end
print("平均值为",average(10,5,3,4,5,6))
5. 元表与元方法
__add
t={a=1}
mt={ --元表
__add=function (a,b)
return a.a+b
end
}
setmetatable(t,mt) -- 把mt设为t的元表
--t的加法被mt的加法替换了
print(t+1) --2
__index
t={a=1}
mt={
__index=function (table,key)
return 123
end
}
setmetatable(t,mt) -- 把mt设为t的元表
print(t['abc']) --123
--t的键没有abc或者t不是table时,会调用__index元方法
t2={a=15}
mt2={
__index={
abc=456,
def=789,
}
}
setmetatable(t2,mt2) -- 把mt设为t的元表
print(t2['abc']) --456
__newindex
t={a=1}
mt={
__newindex=function (table,key,value)
-- rawset(table,key,value)
-- 不能table[key]=value,因为赋值操作也会调用__newindex最后导致堆栈溢出
end
}
setmetatable(t,mt) -- 把mt设为t的元表
t.abc=123 --t原本不存在键abc,会调用__newindex方法
print(t['abc']) --nil
--t不存在这个key或t不是表时,会调用__newindex元方法
语法糖
t={
a=0,
add=function(table,sum)
table.a=table.a+sum
end
}
t:add(10)
-- 等价于t.add(t,10)
print(t['a'])
bag={}
bmt={
put=function(t,item)
table.insert(t.items,item)
end,
take=function(t,key)
return table.remove(t.items,key)
end,
list=function(t)
return table.concat(t.items,",")
end,
clear=function(t)
t.items={}
end
}
bmt['__index']=bmt
function bag.new()
local t={items={}}
setmetatable(t,bmt)
return t
end
local b=bag.new()
b:put("apple")
b:put("banana")
b:put("banana")
print(b:take())-- banana
print(b:list())-- apple,banana
b:clear()
6. 面向对象
Lua 的模块是由变量、函数等已知元素组成的 table
Lua 中的类可以通过 table + function 模拟出来。
至于继承,可以通过 metatable 模拟出来
-- 定义 Person 类
Person = {name = "", age = 0}
-- Person 的构造函数
function Person.new(self,name, age)
local obj = {} -- 创建一个新的表作为对象
setmetatable(obj, self) -- 设置元表,使其成为 Person 的实例
self.__index = self -- 设置索引元方法,指向 Person
obj.name = name
obj.age = age
return obj
end
-- 添加方法:打印个人信息
function Person.introduce(self)
print("My name is " .. self.name .. " and I am " .. self.age .. " years old.")
end
p=Person:new("zhangsan", 100)
p.introduce(p)
p2=Person:new("lisi", 80)
p2.introduce(p2)