内容会持续更新,有错误的地方欢迎指正,谢谢!
前言
上一篇文章:Lua菜鸟教程学习笔记一(基本语法和数据类型)介绍了Lua的基本用法,但缺少一些细节的内容,本文会补充一些细节。
正文
Lua 变量
全局变量、局部变量
Lua 赋值语句
多值赋值:
1.Lua可以对多个变量同时赋值:a, b = 10, 2
等价于a=10; b=2
2.多值赋值经常用来交换变量:x, y = y, x
3.多值赋值还用来将函数调用返回给变量:a, b = f()
,f()返回两个值,第一个赋给a,第二个赋给b。
4.多值赋值时,当变量个数和值的个数不一致时,Lua会一直以变量个数为基础采取以下策略:
a. 变量个数 > 值的个数 按变量个数补足nil
b. 变量个数 < 值的个数 多余的值会被忽略
a, b, c = 0
print(a,b,c) --> 0 nil nil
Lua 索引
对 table 的索引使用方括号 [],t[i]
,gettable_event(t,i) -- 采用索引访问本质上是一个类似这样的函数调用
Lua 循环
while 循环、for 循环、repeat…until重复执行循环,直到 指定的条件为真时为止
--while循环
while( true )
do
print("循环将永远执行下去")
end
--for循环
for a=1,4 do
print(a)
end
--或
local tbl = {"apple", "pear", "orange", "grape"}
for key, val in pairs(tbl) do
print(key,val) --注意:key默认从1开始
end
--repeat...until循环
repeat
print("value of a:", a)
a = a + 1
until( a > 15 )
Lua 流程控制
Lua 把 false 和 nil 看作是"假",其他的都为"真",包括 0 也为 true。
if(0)
then
print("0 为 true")
end
输出为0 为 true
Lua 函数
主要的两种用途:
1.完成指定的任务;
2.计算并返回值,这种情况下函数作为赋值语句的表达式使用。
Lua 编程语言函数定义格式如下:
optional_function_scope function function_name( argument1, argument2, argument3..., argumentn)
function_body
return result_params_comma_separated
end
optional_function_scope为访问修饰符,默认为全局函数,result_params_comma_separated返回值中的每个值以逗号隔开。
函数定义的两种方式:
function max(num1,num2)
if(num1>num2) then
result = num1;
else
result = num2;
end
return result;
end
print(max(41,22))
max = function(num1,num2)
if(num1>num2) then
result = num1;
else
result = num2;
end
return result;
end
print(max(41,22))
函数的多返回值:
-- 调用Lua自有的有多返回值的函数
s, e = string.find("www.runoob.com", "runoob")
print(s, e)
-- 输出为5 10
-- 自定义有多返回值的函数
function maximum (array)
......
return m, mi
end
print(maximum({8,10,23,12,5})) --array是一个数组
可变参数:
1.在函数参数列表中使用三点 … 表示函数有可变的参数:
function add(...)
local s = 0 -- 这里对不对齐都行,反正是通过end来标志一个函数的结束,出于代码整洁,最好要对齐
for i, v in ipairs{...} do --> {...} 表示一个由所有变长参数构成的数组
s = s + v
end
return s
end
print(add(3,4,5,6,7))
2.可以将可变参数赋值给一个变量:
function average(...)
result = 0
local arg={...} --> arg 为一个表,局部变量
for i,v in ipairs(arg) do
result = result + v
end
print("总共传入 " .. #arg .. " 个数")
return result/#arg -- #arg就可以得到表中的元素个数
end
print("平均值为",average(10,5,3,4,5,6))
3.也可以通过 select("#",…) 来获取可变参数的数量:
function average(...)
print("总共传入 " .. select("#",...) .. " 个数")
end
print("平均值为",average(10,5,3,4,5,6))
-- 输出:总共传入 6 个数
总结:调用select时,必须传入一个固定实参selector(选择开关)和一系列变长参数。如果selector为数字n,那么select返回它的第n个可变实参,否则只能为字符串"#",这样select会返回变长参数的总数。
4.有时候我们可能需要几个固定参数加上可变参数,固定参数必须放在变长参数之前:
function fwrite(fmt, ...) ---> 固定的参数fmt
return io.write(string.format(fmt, ...)) --io.write不会自动换行,print会自动换行,string.format用于格式化字符串
end
fwrite("runoob\n") --->fmt = "runoob", 没有变长参数
fwrite("value is %d%d\n", 1, 2) --->fmt = "%d%d", 变长参数为 1 和 2
输出:
runoob
value is 12
Lua 运算符
算术运算符、关系运算符就不说了
逻辑运算符:且为and,或未or,非为not
其他运算符:..
连接两个字符串,#
为一元运算符,返回字符串的长度#"Test"
或表的长度#arg --假设arg为表的名字
运算符优先级:从高到低的顺序为
^
not - (一元的)
* /
+ -
..
< > <= >= ~= ==
and
or
Lua 字符串
Lua 语言中字符串可以使用以下三种方式来表示:单引号间的一串字符string1 = 'runoob.com'
、双引号间的一串字符string1 = "Lua"
、[[和]]间的一串字符string3 = [["Lua 教程"]]
**字符串操作:**一堆API,需要的时候查就好了
比如:求字符串长度print("字符串长度 ",string.len(string2))
字符串格式化:string.format()
--%c - 接受一个数字, 并将其转化为ASCII码表中对应的字符
string.format("%c", 83) 输出S
--%d,或%i - 接受一个数字并将其转化为有符号的整数格式
string.format("%d", 17.0) 输出17
string.format("%05d", 17) 输出00017
string.format("日期格式化 %02d/%02d/%d", date, month, year) --输出为:日期格式化 02/01/2014
--%u - 接受一个数字并将其转化为无符号整数格式
string.format("%u", 3.14) 输出3
--%f - 接受一个数字并将其转化为浮点数格式
string.format("%6.3f", 13) 输出13.000 --总占用6位(以右为锚点),并显示3位小数
string.format("%.4f",1/3)
--%s - 接受一个字符串并按照给定的参数格式化该字符串
string.format("%s", "monkey") 输出monkey
string.format("%5.3s", "monkey") 输出 mon --总占用5位(以右为锚点),并显示3个字符
Lua 数组
一维数组:
array = {"Lua", "Tutorial"}
for i= 0, 2 do
print(array[i])
end
输出:因为索引默认从1开始
nil
Lua
Tutorial
多维数组: 以下是一个三行三列的多维数组:
-- 初始化数组
array = {}
for i=1,3 do
array[i] = {}
for j=1,3 do
array[i][j] = i*j
end
end
-- 访问数组
for i=1,3 do
for j=1,3 do
print(array[i][j])
end
end
Lua 迭代器
1.泛型 for 迭代器提供了集合的 key/value 对,语法格式如下:
for k, v in pairs(t) do
print(k, v)
end
2.无状态的迭代器
无状态的迭代器是指不保留任何状态的迭代器,因此在循环中我们可以利用无状态迭代器避免创建闭包花费额外的代价。每一次迭代,迭代函数都是用两个变量(状态常量和控制变量)的值作为参数被调用,一个无状态的迭代器只利用这两个值可以获取下一个元素。这种无状态迭代器的典型的简单的例子是ipairs,它遍历数组的每一个元素。
被遍历的表被叫做状态常量(循环过程中不会改变的),当前的索引下标被叫做控制变量
function iter (a, i)
i = i + 1
local v = a[i]
if v then
return i, v
end
end
function ipairs (a)
return iter, a, 0
end
当Lua调用ipairs(a)开始循环时,他获取三个值:迭代函数iter、状态常量a、控制变量初始值0;然后Lua调用iter(a,0)返回1,a[1](a[1]=nil这种情况除外);第二次迭代调用iter(a,1)返回2,a[2]……直到第一个nil元素。
3.多状态的迭代器
很多情况下,迭代器需要保存多个状态信息而不是简单的状态常量和控制变量,最简单的方法是使用闭包,还有一种方法就是将所有的状态信息封装到table内,将table作为迭代器的状态常量,因为这种情况下可以将所有的信息存放在table内,所以迭代函数通常不需要第二个参数。
array = {"Lua", "Tutorial"}
function elementIterator (collection)
local index = 0
local count = #collection
-- 闭包函数
return function ()
index = index + 1
if index <= count
then
-- 返回迭代器的当前元素
return collection[index]
end
end
end
for element in elementIterator(array)
do
print(element)
end
以上实例输出结果为:
Lua
Tutorial
Lua table(表)
table 是 Lua 的一种数据结构用来帮助我们创建不同的数据类型,如:数组、字典等。
表的构造:
-- 初始化表
mytable = {}
-- 指定值
mytable[1]= "Lua"
-- 移除引用
mytable = nil
-- lua 垃圾回收会释放内存
表的操作:
1.Table 连接
table.concat (table [, sep [, start [, end]]])
table.concat()函数列出参数中指定table的数组从start位置到end位置的所有元素, 元素间以指定的分隔符(sep)隔开。
fruits = {"banana","orange","apple"}
-- 返回 table 连接后的字符串
print("连接后的字符串 ",table.concat(fruits))
-- 指定分隔符
print("连接后的字符串 ",table.concat(fruits,", "))
-- 指定开始索引和结束索引来连接 table
print("连接后的字符串 ",table.concat(fruits,", ", 2,3))
执行以上代码输出结果为:
连接后的字符串 bananaorangeapple
连接后的字符串 banana, orange, apple
连接后的字符串 orange, apple
2.插入和移除
table.insert (table, [pos,] value)
在table的数组部分指定位置(pos)插入值为value的一个元素. pos参数可选, 默认为数组末尾
fruits = {"banana","orange","apple"}
-- 在末尾插入
table.insert(fruits,"mango")
print("索引为 4 的元素为 ",fruits[4])
-- 在索引为 2 的键处插入,原来键为2及其以后的键值对全部后移一位
table.insert(fruits,2,"grapes")
print("索引为 2 的元素为 ",fruits[2])
-- 由于上方插入了一个数,所以最后一个元素的索引为5
print("最后一个元素为 ",fruits[5])
table.remove(fruits)
print("移除后最后一个元素为 ",fruits[5])
执行以上代码输出结果为:
索引为 4 的元素为 mango
索引为 2 的元素为 grapes
最后一个元素为 mango
移除后最后一个元素为 nil
3.Table 排序
fruits = {"banana","orange","apple","grapes"}
table.sort(fruits)
排序后
apple
banana
grapes
orange
接下来的内容,请见Lua菜鸟教程学习笔记三(重难点)