Lua标准字符串库
string.rep("abc",3) ababab
string.reverse("A Long Line!") !eniL gnol A
string.lower("A Long Line!") a long line!
string.upper("A Long Line!") A LONG LINE!
string.sub("abcdef",2,4) bcd
string.char(97) a
string.byte("abc",-1) 99
string.format("x = %d y = %s",22,tang)
string.find(“hello world”,""wor) 7 9
string.gsub("hello world","l",".") he..o wor.d
Lua的UTF8支持库
lua除了字节操作的不能对utf8使用其他都可以用
utf8.len("aaaa") 4
utf8.char(114,223) 等价于string.char
utf8.codepoint(“abcd”,utf8.offset("abcd",4)) 等价于string.byte,但是注意是下标是字节操作的,如果要选中指定的字符需要使用这种办法
utf8.offset("abcd",4) 获得指定字符所在的字节位置
utf8.codes("aaa") 遍历字符串,将每个字符的数据返回出来,有两个返回值,一个是在字符串中的字节位置第二个是该字符的utf编码
Lua的表
lua的复杂类型都是基于表来实现的,包括函数库和全局变量等
lua的表变量是指针,所以当a=b时候,a和b都是指向同一个表
lua的表可以用任意的字符串数组和浮点数来做key,不存在的key会返回nil,当没有指针指向表则最终这个表会被回收
lua中下标索引和方法是可以通用的,也就是说这三种调用都是合理的:a[b] a.b a:b
此外要注意下标中的数字和数字字符串是两种key,而字符串和同名变量也是两种key,但是相等的整型和浮点型则是同一种key
Lua的表构造器
lua的表从1开始计数,有多种表的声明方式:
zero = {} zero["a"]="b"
a={"a","b","c"}
b={x=10,b=20}
c={[1] = 11,[2] = 13}
此外多种构造器都能一起使用,如
d={x=11,h=22,33,44,{x=1,y=5},["a"]=22,} (PS:末尾的逗号可以不用省略)
Lua的数组、列表和序列
使用#符号可以获得表里面的序列长度,序列即为指定的n个正整数数值组成的集合[1...n]
通过这个特性可以进行以下操作:
a[#a] = nil 移除最后一位
a[#a+1] = value 在最后追加一个值
但是也要注意避免对可能的空洞列表进行操作(PS:空洞列表即指从1到n之间有nil的,其将会返回n而不是实际长度,而假如最后一位nil的话,则会返回到最后一位非nil的长度),假如需要对这种列表操作长度,最好明文保存
Lua的表遍历
pairs(t) 可以遍历表,返回值有两个,分别是key和value。但是要注意这样遍历出来的值是随机顺序的,唯一能保证的是每个都只出现一次
ipairs(t) 使用列表(即{11,22,33}这种)的话可以用这个函数,返回值一样,但是可以保证是按顺序遍历。
此外数值型列表也可以使用for循环,如:
for k = 1,#d do
print(d[k])
end
Lua表的安全访问
当需要访问嵌套表的时候,很容易调用到不存在的表,导致错误。可以使用:
data = a and a.b and a.b.c
但是这样写长了容易写错,而且对表进行多次访问,可以改成下面这种
data = ((a or {}).b or {}).c
这样避免了错误调用,此外每个都只写一次,减少了重复访问表
Lua表的方法
table.insert(t,item) 在t末尾添加item
table.insert(t,index.item) 在t的index位置插入item,并把index原先的值和后面的值往后推一位
table.remove() 删除指定位置的值
通过这两个方法,可以实现栈、队列、双向队列
table.move(a,f,e,t) 将a表的f到e之间的元素移动到a表的t位置上,注意这里是拷贝,假如原先位置的值不需要了,要手动赋值nil
table.move(a,f,e,t,b) 将a表的f到e之间的值拷贝到b表的t位置上
Lua的函数
lua的函数指从function到end之间的代码段,需要注意的是函数的输入参数和输出参数都是可变的即:
当函数要求多个输入而调用没给足时候,少的输入位会被赋值nil,而调用时候给多了则被忽略
当函数被当作单独语句调用则返回值全部舍弃,当函数作为表达式调用则只保留第一个返回值,当函数调用是一系列表达式的最后一个表达式的时候,其所有返回值才能被获得(PS:指传入参数、多重赋值、表构造器和return语句)
Lua可变长参数
当使用function a(...) do end 这样的时候,代表是可变参函数,可以传入任意长度参数,遍历时候则直接遍历:
function foo(...)
for key, value in pairs{...} do
print(key,value)
end
end
当然也可以这么写 function foo(fmt,...) local a,b,c = ... end
但是当出现nil值的时候,遍历就会出现问题,因为nil会被跳过。这时候可以使用table.pack()方法,这会对...进行再次封装,多出来一个n变量保留变量长度(包含nil的)这时候可以这么用:
function foo(...)
local arg = table.pack(...)
for i = 1,arg.n do
print(arg[i])
end
end
foo(11,22,nil,33)
而此外还能使用select()来对可变数组操作:
select(2,"a","b","c") b c
select("#","a","b","c") 3
通过这样,可以这样写
function foo(...)
for i =1,select("#",...) do
print(select(i,...))
end
end
foo(11,22,33)
Lua的table.pack和table.unpack
table.pack可以把一组数据变成真实表,而table.unpack则是把真实表变成一组返回值
Lua的尾调用
当a函数调用b函数之后,没有任何其他操作,则b函数为a函数的尾调用。Lua对此的优化是,当发现b为尾调用的时候,a的数据将不会被压入栈而是被释放,b执行完将会直接返回到a的调用者。
要注意什么是尾调用,即直接return出去,直接调用去不返回或者说在return时候做计算都是额外操作。