Lua语言的数据类型很是丰富,包括nil、boolean、number、string、userdata、function、thread 和 table等类型。Lua中全部的数据类型的默认值都是nil。html
只有一个值,就是nil自己。数组
跟其余语言同样,包括false和true俩个值。 在lua语言中,只有nil和false的值为“假”,其余的都是“真”bash
number类型表示双精度浮点数字,lua中没有整数类型,全部的数字类型都是number,这个跟js实际上是同样的。 咱们能够省略小数部分和指数部分,下面这些都是有效的number类型。数据结构
4 0.4 4.57e-3 0.3e12 5e+20
复制代码
首先String在lua中是不可能的值,这个跟大多数语言中的string类型设计是同样的,好比Java和JavaScript,Go等等(C语言的string是可变的)。 因此,若是在lua中你须要修改一个字符串,你能够像下面这样,从新生成一个新的字符串。函数
a = "one string"
b = string.gsub(a, "one", 'another') -- 讲one替换为another
print(a) --> one string
print(b) --> another string
复制代码
注意看上面的代码,单引号和双引号均可以表示一个字符串。这点跟js也同样。ui
在lua中,lua会自动管理字符串的内存释放和回收,因此不用担忧内存问题。编码
在lua中,字符串里面能够包含转义字符,和js不一样的是,lua中可使用转义的数字来表示ASCII编码。举个例子:lua
"alo\n123\""
'\97lo\10\04923"'
复制代码
上面这两个字符串是相等的,由于a的ASCII码是97,换行符\n的ASCII码是10,数字1的ASCII码是49。因此上面的两个字符串是彻底同样的。spa
lua中若是想表示多行字符串,可使用[[...]],而且能够嵌套。可是这种字符串表示,不会去解析转义字符。线程
[[ <div> <span>hello</span> <p> .... </p> </div> ]]
复制代码
lua中对于字符串的任何数字操做,都会尝试将字符串转换为数字类型。
print("10" + 1) --> 11
print("10 + 1") --> 10 + 1
print("-5.3e-10"*"2") --> -1.06e-09
print("hello" + 1) -- 错误:stdin:1: attempt to perform arithmetic on a string value
print(1 + "hello") -- 错误:stdin:1: attempt to perform arithmetic on a string value
复制代码
这里跟js里面仍是有区别的,js里面,第一个会输出“101”,第四个会输出“hello1”,第五个会输出“1hello”。
与上面相反,lua中对于数字的任何字符串操做,都会讲数字转换为字符串。
print(1 .. 3) --> 13
复制代码
这里的..是lua中的字符串相加的操做。注意..前的空格,不然会被当作是前一个数字的小数点。后面的空格没有关系。
对于上面,你会以为lua中的字符串和数字会自动转换,那比较的时候,是否也会自动转换呢?答案是不会转换。
print(1 == "1") --> false
复制代码
咱们知道在js里面若是使用1=='1'来判断是否相等,会返回true,必须使用===来使用强相等的判断,这点lua中不须要。lua中会直接判断类型是否相同, 若是不一样直接返回false。\
若是须要字符串和数字比较,那就须要先将字符串转换为数字或者将数字转换为字符串:
print(1 == tonumber('1')) --> true
print(tostring(1) == '1') --> true
复制代码
tonumber和tostring不用说你也知道是干吗的。 官方文档:www.lua.org/pil/2.4.htm…
lua中的table类型有点相似js中的对象,可是比js中的对象更增强大。它能够表示数组,set,队列等各类数据结构。lua中的table是引用类型,这意味着不会存在数据复制和拷贝的问题。操做table就是在操做指针,背后也没有副本或者新table的建立。
a = {} --> 声明一个table
复制代码
而后能够给这个table各类操做:
a[1] = "1"
a["k"] = "v"
复制代码
基本上你在js里面怎么使用对象,这里就能够怎么使用lua的table,是否是很简单?
再来看个例子:
const a = {};
a['1'] = 1;
a[1] = 2;
console.log(a[1]) // 2
console.log(a['1']) // 2
复制代码
a = {}
a['1'] = 1
a[1] = 2
print(a[1]) --> 2
print(a['1']) --> 1
复制代码
注意上面这一个区别,js中是会将key转换为字符串的。而在lua中,是不会的。
除了上面这种a[1]形式访问table中的属性外,还能够经过a.x,a.y的形式访问,可是注意,x,y不能是数字。因此上面的a[1]和a['1']都不能使用这种形式。
注意: a.x和a.y这种形式,是经过x,y的值去访问table中的属性,而a[x]和a[y]是经过x,y自己做为索引去访问table,这里是有区别的:
x = 10
a = {}
a[x] = 1
a.x = 2
print(a[x]) --> 1,这里的key是10
print(a.x) --> 2,这里的key是“x”
复制代码
这个跟js里面是同样的。
a = {}
a[0] = 'one'
a[1] = 'two'
a[2] = 'three'
for i,line in ipairs(a) do
print(i .. '-->' .. line)
end
复制代码
上面的代码输出以下:
1-->two
2-->three
复制代码
为何0不见了呢?由于在lua语言中,索引是从1开始的,这是一个约定,全部内建的函数和功能都是这个约定。 上面的代码你能够经过a[0]来显示访问到这个值。不过建议不要这么作。
function类型是lua中的一等公民。嗯,js里面是否是也是这样?
function add (a)
local sum = 0
for i,v in ipairs(a) do
sum = sum + v
end
return sum
end
复制代码
a={}
a[1]=1
a[2]=2
add(a) --> 3
复制代码
这种类型是专门用来在lua中表示由C语言建立的各类数据类型的。这里就先不看, 由于不多须要用到这个。
在lua中,有一个coroutine(协程)的概念,他跟线程有点相似,lua中的协程有本身的局部变量,可是共享全部的全局变量。在同一时间只会执行一个协程,这点跟线程是不同的,线程是同一时间会执行多个线程。
co = coroutine.create(function ()
print("hi")
end)
print(co) --> thread: 0x8071d98
print(type(co)) --> thread
复制代码
在coroutine中,有一个create函数。经过这个函数能够建立出一个thread类型变量,注意这里表示建立了一个协程。
lua中的协程有3种状态,suspended,running,dead。 刚刚建立的协程的初始化状态是suspended,也就是说协程不会自动的运行,能够经过下面的代码查看协程的状态。
print(coroutine.status(co)) --> suspended
复制代码
使用如下代码来启动一个协程:
coroutine.resume(co) --> hi
print(coroutine.status(co)) --> dead
复制代码
在js中咱们知道,有一个关键字yield,用来暂停生成器函数的执行。举个例子,
function *test(){
yield 1
yield 2
return 3
}
const testGe = test();
testGe.next() // {done: false, value: 1}
testGe.next() // {done:false, value: 2}
复制代码
生成器函数test被调用的时候回返回一个生成器。这个生成器每次调用next的时候 就会执行函数的代码,直到遇到yield关键字就暂停执行。
相似的,在lua中也有yield,咱们来看个例子:
co = coroutine.create(function ()
for i=1,10 do
print("co", i)
coroutine.yield()
end
end)
复制代码
看上面的代码,当咱们执行coroutine.resume(co)的时候,都会执行协程中的代码,可是当遇到coroutine.yield()的时候灰停在协程的执行。
运行一次的输出结果:
coroutine.resume(co) --> co 1
print(coroutine.status(co)) --> suspended
复制代码
运行第二次:
coroutine.resume(co) --> co 2
print(coroutine.status(co)) --> suspended
复制代码
发现没有,这里和js中的生成器函数那货是否是很是的相似? 确定的,你运行10次以后,再去查看co的状态,确定是dead状态了。你本身去试试吧。
使用了yield的协程函数内部,怎么传递参数呢?看下面的例子:
co = coroutine.create(function (p)
for i=1,10 do
coroutine.yield(p + i)
end
end)
复制代码
在上面的例子中,咱们给协程函数添加了一个参数p,而且在调用coroutine.yield的时候,执行p+i的表达式,这个表达式执行的结果,就是该次执行协程的返回结果。
咱们来看下: 第一次运行:
print(coroutine.resume(co, 1)) --> 2
复制代码
第二次运行:
print(coroutine.resume(co, 1)) --> 3
复制代码
看到这里你应该明白了,每次执行resume的时候,都是执行到yield位置暂停,而后执行yield中的表达式,而后将结果返回。 官方文档: www.lua.org/pil/9.html
原文地址:codebe.org