lua 是动态类型语言,变量使用前不需要定义类型,在使用时直接赋值即可。
1 基本数据类型
值可以存储在变量中,作为参数传递或作为结果返回。
lua中有八个基本数据类型:
- nil 只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)
- boolean 布尔类型, true 和 false
- number 双精度浮点数
- string 字符串,可由一对单引号或双引号表示
- userdata 表示任意存储在变量中的 C 数据结构
- function 由C 或 lua 编写的函数
- thread 表示执行的独立线程,用于执行协同程序
- table lua中的表,其实是一个关联数组,数组的索引可以是数字、字符串或表类型。在Lua里 table 的创建是通过构造表达式来完成,最简单构造表达式是{},用来创建一个空表。
2 获取数据类型
通过函数 type 可以返回一个值或一个变量所属的数据类型。
代码语言:javascript复制print(type("hello"))
print(type(23))
print(type(23.3))
print(type(true))
print(type(nil))
print(type(function() end))
输出如下
string number number boolean nil function
整数和浮点数在lua中,都属于 number 实数类型。
2.1 nil
nil 是一种空数据类型,在 lua 中将 nil 用于表示“无效值”。变量在首次赋值前的默认值,就是 nil,将 nil 赋给全局变量后,即等同于删除该变量。
代码语言:javascript复制-- 定义变量,但是没有赋值
local abc
print(abc)
print(type(abc))
-- 为变量赋值
abc = "hello"
print(abc)
print(type(abc))
输出如下:
nil nil hello string
在赋值前该变量及变量类型都为nil,赋值后变量及变量类型随之改变。
2.2 boolean
布尔类型,取值只有 true 和 false。
lua 中,当变量为 nil 或 false 时,其布尔值为 false,其他数值均为 true。
代码语言:javascript复制-- 变量未赋值时,值为nil
local boo
if boo then
print("true")
else
print("false")
end
-- 给变量赋值为 false
local boo = false
if boo then
print("true")
else
print("false")
end
输出都为 false
代码语言:javascript复制false false
-- 给变量赋值为0
local boo = 0
if boo then
print("true")
else
print("false")
end
-- 给变量赋值为空字符串
local boo = ""
if boo then
print("true")
else
print("false")
end
当变量值为非nil 及 false 时,取值都为 true。
true true
2.3 number
lua 中没有区分整数和小数,所有数字统一为number类型,即实数。
number的计算方法主要来自于 math 类
代码语言:javascript复制-- 向上取整
print(math.ceil("3.1415926"))
-- 向下取整
print(math.floor("3.1415926"))
-- 绝对值
print(math.abs(-3.1415926))
输出如下
4 3 3.1415926
2.4 string
在 lua 中字符串表示有三种方式:
- 双引号
- 单引号
- [[]]包裹
local s1 = "hellonworld"
local s2 = 'hellonworld'
local s3 = [[hellonworld]]
print(s1)
print(s2)
print(s3)
其中在单引号、双引号定义的字符串,如果存在转义符时,会对其转义输出;
而由 [[]] 包裹的字符串,不会对转义字符进行转义,仅将其原样输出。
hello world hello world hellonworld
字符串的内化:如果有多个完全一样的字符串,在lua中仅会保存一份。
2.5 table
- 数组, 索引从1开始
- 数组索引可以是任意类型,但必须是唯一的,类似于java中的map的key,或者python中的dict的key
- 数组元素可以是任意类型,也可以是数组
- 数组的长度是固定的,不能动态改变
- 数组可以嵌套
local ta = {
name = "ticktok",
age = 23,
sex = true,
honor = {
"swim",
"run",
"sleep"
},
001002003, -- 索引没有,相当于[1]
7759521, -- 索引没有,相当于[2]
[1] = "hello", -- 索引重复,该值不会被保存
["key"] = "value",
[1.2] = "world",
}
定义一个 table 类型的数据,前边是索引,后边是索引对应的数据。
需要注意的是:
- 如果没有设置索引时,该数据对应的索引默认从[1]开始,lua 数组中索引的下标从1开始
即
代码语言:javascript复制local ta = {
001002003, -- 索引没有,相当于[1]
7759521, -- 索引没有,相当于[2]
}
print(ta[1])
输出如下
1002003
- 索引不能重复,当显示设置的索引重复时,新数据会覆盖老数据
local ta = {
[1.2] = "world",
[1.2] = "world23",
}
print(ta[1.2])
输出如下
world23
- 当隐式索引数据与显示索引重复时,无论顺序怎样变化,该索引始终显示为隐式索引定义的数据
local ta = {
[1] = "hello", -- 索引重复,该值不会被保存
001002003, -- 索引没有,相当于[1]
7759521, -- 索引没有,相当于[2]
}
print(ta[1])
输出如下
1002003
- 当数组中包含了table数据,仍然可以根据索引,引用或输出该数据
local ta = {
honor = {
"swim",
"run",
"sleep"
},
}
print(ta.honor[1])
输出如下,数据的索引从1开始
swim
- 当引用的索引不存在时,输出为 nil
print(ta["abc"])
输出
nil
2.6 function
lua 中函数也可以作为变量使用。
代码语言:javascript复制-- 定义一个函数
local function foo()
local x = 3
local y = 7
return x y
end
-- 将函数赋值给变量
local c = foo
print(c())
-- 将函数赋值给变量2
local c = foo()
print(c)
将函数赋值给变量时,函数名后不带()和带有()在引用变量时会有区别:
- 赋值时不带(),在使用变量时就需要在变量名后补充()
- 赋值时带有(),在使用变量时就不需要在变量名后再补充()
函数也可以如下使用,将赋值和定义放在一起。
代码语言:javascript复制local c2 = function()
local x = 3
local y = 7
return x * y
end
print(c2())
2.7 thread
在 lua 里,最主要的线程是协同程序(corourtine),与线程(thread)类似,拥有独立的栈、局部变量和指令指针,可以跟其他协同程序共享全局变量等信息。
线程与协程的区别:
- 线程可以同时多个运行,协程在任意时刻只能运行一个,且处于运行状态的协程只有被挂起时,才会暂停。
2.8 userdata(用户自定义类型)
一种由用户自定义的数据,用于表示一种由应用程序或 C/C 语言库所创建的类型,可以将任意C/C 的任意数据类型的数据存储到 lua 变量中调用。