初始lua
- lua是轻量小巧的脚本语言,它用标准C编写,开放源码。意味着lua的虚拟机可以很方便嵌入到别的程序里面,从而为应用程序提供灵活的扩展和定制功能。
- 整个lua虚拟机编译后仅仅100K+,经过裁剪还能更小。
- 在目前的脚本引擎中,lua的运行速度占有绝对的优势。
number变量
- 给一个变量赋值,就是声明一个变量。变量默认是全局变量。
- nil类型表示没有任何的有效值,只要是没有声明的变量,它就是nil
- lua可以给多个变量同时赋值,变量使用逗号分开,赋值语句右边的值会依次赋给左边的变量。
- number是数组类型,支持0x赋值和科学计数法。
> a = 0x10
> b = 10e2
> print(a, b)
16 1000.0
- lua5.3支持左移和右移
> a = 2
> print(a>>1, a<<1)
1 4
字符串
- [[]]之间的字符原样输出,不进行转义。
- 连接符号为.., c = a..b
- tostring, tonumber
> tostring(0x12)
18
> tonumber("0x12")
18
逻辑运算
- 不等于是~
- and, or, not(逻辑非)
它满足短路求值,并且返回的是变量的值而不是。只有not返回的单纯是false或true
b > 10 and "yes" or "no"
分支判断
- if语句
if 条件 then
...
elseif condition then
...
else
...
end
函数
- 在lua中,函数也是一种变量类型。
function hello() print("hello world") end
也就是hello实际上也是一个变量,里面存储的是一个函数。所以我们也可以这样声明hello函数
hello = function() print("hello world") end
- 使用local创建一个局部变量,和全局变量不同,局部变量只在被声明的那个代码块内有效。
- 我们应该尽可能使用局部变量,以方便lua虚拟机自动回收内存空间。
- 传给函数的参数,等价于在函数内部新建了一个local变量。
- return可以返回多个值。
table
- 在lua中,我们可以使用table来实现数组的功能。
- 实际上,table中可以包括任意类型的数据,number,string,甚至还可以放function变量。
- 实际上,lua中的下标可以直接在声明的时候指定。
t = {
[1] = 6,
}
--使用["下标"] = 值
--和 下标 = 值
--都是正确写法
--当第二种方式有歧义时,应该用第一种方式
--可以用下面两种方式访问:
print(t["apple"])
--输出10
print(t.apple)
--输出10
--当第二种方式有歧义时,应该用第一种方式
- string作为下标的时候,也可以动态的赋值
t={}
t["new"] = "newvalue"
- 在table中,我们直接使用table[下标]或table.string下标来访问元素。
- 实际上,在lua中,所有全局变量都被存放在一个大的table中,这个table名为_G
t = 1
> _G.t
1
> _G["t"]
1
> _G.print("hello")
hello
> _G["print"]("hello")
hello
- 万物基于table。
- table.concat(table [,sep] [,i [,j]])
将元素是string或者number类型的table,每个元素连接起来变成字符串并返回。
可选参数sep,表示连接的间隔符,默认为空。
i和j表示元素起始和结束的下标。
> a = {1,2,3,"hello",34, "worrd"}
> print(table.concat(a, "-"))
1-2-3-hello-34-worrd
- table.insert(table, [pos,] value
在数组型的表table的pos索引位置插入value,其他元素向后移动到空的地方。pos的默认位置是表达长度加1,也就是插在表的最后 - table.remove(table [,pos])
在表table中删除索引为pos的元素(pos只能是number类型),并返回这个被删除的元素,它后面所有的元素的索引值都会减1.pos的默认值是表的长度,也就是默认删除表最后一个元素。
> a = {1,8}
> table.insert(a, 2)
> print(table.concat(a, "|"))
1|8|2
> table.remove(a, 1)
1
> table.remove(a, 1)
8
> print(table.concat(a, "|"))
2
while循环
while condition do
...
end
while n<10 do n = n+1 print(n) end
for循环
for 临时变量名=开始值,结束值, 步长 do --步长可以省略,默认为1
...
end
- 中断循环
在for循环和while循环中,我们都可以使用break来中断循环。 - string库
- string.sub(s, i, [,j])
返回字符串s中从索引i到索引j之间的子串。i可以为负数,表示倒数第几个字符。当j缺省的时候,默认为-1,表示字符串s的最后位置。当i在j之后,则返回一个空串
> s = "helleworld"
> string.sub(s, 1, -2)
helleworl
> s:sub(1, -2) --我们可以使用冒号来简化语法
helleworl
- string.rep(s, n)
返回字符串s的n次拷贝。rep: 应该是repetition的意思
> s = "hello"
> string.rep(s, 2)
hellohello
> s:rep(2)
hellohello
- string.len(s)
接收一个字符串,返回它的长度。
> string.len("hello")
5
> "hello":len()
stdin:1: unexpected symbol near '"hello"'
> ("hello"):len()
5
- string.lower(s): 把所有大写字母都转换为小写字母的字符串
string.upper(s):把所有小写字母都变成大写字母的字符串
> string.lower("WER123are")
wer123are
> string.upper("WER123are")
WER123ARE
- string.format(formatstring, ...)
按照格式化参数formatstring, 返回后面...内容的格式化版本。
编写格式化字符串的规则和标准c语言中的printf函数的规则基本上相同。 - string的本质
- 字符串是用来存储字符,它的本质就是一串数字。如果用一串数字代表一串字符?在计算机中,每一个符号都对应这一个数字,比如符号0对应的数字为0x30,这样的编码规则,我们称为ascii码。所以我们看到字符串apple1, 其本质上就是一串数字: 0x61, ....., 0x30等。
- 一个字节表示的最大数为0xff,能够表示256个符号。大部分的中文按照某种编码,一个中文占用2或者3个字节。
- lua中的字符串可以保存任何值,所以0x00也可以保存。但是在c语言中,0x00数字表示字符串的结束。
- string.char(...)
接受0个或者更多的整数,整数范围为0-255, 返回这些整数所对应的ascii字符组成的字符串。当参数为空时,默认是一个0.
> string.char(0x30,0x31,0x32,0x33,0x34)
01234
- string.byte(s [,i [,j]])
返回字符s[i],到s[j]之间字符对应的数字。i默认值为1, 也就是第一个字节。j的默认值为i
> string.byte("hello",1, string.len("hello"))
104 101 108 108 111
- string.find(s, p [,init [,plain]])
- 这个函数会在字符串s中,寻找匹配p字符串的数据。如果成功找到,那么会返回p字符串在s字符串中出现的开始位置和结束位置。如果没有找到,那么就返回nil。
- init的默认值为1,表示从第几个字符开始匹配,当init为负值,表示从字符串s的倒数第几个位置开始匹配。
- plain默认为为false,当其为true,只会把p看成一个字符串。
plain存在的意义:实际上,lua中的匹配默认意义是正则匹配。所以如果为false,应该看做是正则表达式
> string.find("helloworld", "lo", 1, true)
4 5
- string.gsub(s, p, r [, n])
将目标字符串s中所有子串p替换成字符串r. 可选参数n表示限制替换的次数。
返回值有两个:第一个是替换后的字符串,第二个是替换了多少次。
> string.gsub("helloworld", "l", "-", 100)
he--owor-d 3
跨文件调用
- 新建一个tools.lua, 文件如下
local function gettable(max)
local t = {}
for i=1,max do
table.insert(t, i)
end
return t
end
return {gettable = gettable,} --手动返回一个table,包含上面的函数
- 在其他文件中调用封装的函数
tool = require("tools") --引用tools.lua文件并加载
local t = tool.gettable(8)
print(table.concat(t, ","))
#1,2,3,4,5,6,7,8
当调用了require接口后,lua虚拟机会自动加载调用的文件,执行文件中的内容,然后返回文件里return的结果。tools.lua文件返回了一个table。
- 每个文件最多只会被require一次,如果有多个require,只有第一次会执行。
- require后面跟的包名不带扩展名。
- 如果引用不同目录的包,目录层级用.进行分割。
package.path = package.path .. ";./path/?.lua" --增加当前目录下的path目录作为路径
next
> t = {a=1,b=2,c=3}
> next(t)
c 3
> next(t, "c")
b 2
> return next(t, "b")
a 1
> return next(t, "a")
nil
> t = {}
> next(t) --常常用next(t)作为判断t是不是空表
nil
lua中的字符串的分割的区间是左闭右闭区间
> str = "123456"
> return string.sub(str, 1, 2)
12
> return string.sub(str,1)
123456