Lua 教程 - 第二章:数据类型与值
第二章:数据类型与值
在 Lua 中,值(Value)是一等公民,而变量本身没有类型,只有值才有类型。这意味着你可以将任何类型的值赋给任何变量。Lua 是一种动态类型语言,这为编程带来了极大的灵活性。
本章将详细介绍 Lua 的 8 种基本数据类型,并深入探讨字符串和表(Table)的基础用法。
2.1 基本数据类型
Lua 包含以下 8 种基本数据类型:
| 类型 | 描述 |
|---|---|
| nil | 空值,表示无效值。 |
| boolean | 布尔值,包含 true 和 false。 |
| number | 数字,Lua 5.3+ 支持整数和浮点数。 |
| string | 字符串,字符序列。 |
| function | 函数,由 C 或 Lua 编写。 |
| userdata | 用户数据,用于存储 C 数据结构。 |
| thread | 线程,用于协程(Coroutine)。 |
| table | 表,Lua 中唯一的数据结构。 |
我们可以使用 type() 函数来检查值的类型:
print(type("Hello")) -- string
print(type(10)) -- number
print(type(print)) -- function
print(type(nil)) -- nil
print(type(true)) -- boolean
nil (空)
nil 是一种特殊的类型,它只有一个值 nil。它主要用来表示“无值”或“无效值”。全局变量在第一次赋值前默认值为 nil。将全局变量赋值为 nil 相当于删除了该变量。
boolean (布尔)
布尔类型有两个值:true 和 false。
重要提示:在 Lua 中,除了 false 和 nil 视为假(false),其他所有值都视为真(true)。这意味着数字 0 和空字符串 "" 在 Lua 中都被视为 true。
number (数字)
Lua 5.3 引入了整数(integer)和浮点数(float)的区分。
-
整数:64 位有符号整数。
-
浮点数:双精度浮点数(符合 IEEE 754 标准)。
通常情况下,你不需要关心它是整数还是浮点数,Lua 会自动处理。
a = 10 -- 整数
b = 10.5 -- 浮点数
c = 1e-3 -- 科学计数法 0.001
string (字符串)
字符串是不可变的字节序列。你可以使用单引号 ' 或双引号 " 来界定字符串。
s1 = "Hello"
s2 = 'World'
还可以使用 [[...]] 来表示多行字符串,这种方式不会解释转义序列:
html = [[
<html>
<head></head>
<body>
<a href="http://www.lua.org">Lua</a>
</body>
</html>
]]
table (表)
表是 Lua 中最强大且唯一的数据结构。它可以用来实现数组、字典、集合、队列、类、模块等。我们将在 2.3 节详细介绍。
function (函数)
函数是第一类值(First-class values),这意味着函数可以像数字或字符串一样存储在变量中、作为参数传递给其他函数,或者作为返回值返回。
userdata (用户数据)
userdata 允许将 C 语言的数据结构存储在 Lua 变量中。这通常用于 Lua 与 C 的交互,在纯 Lua 脚本中无法创建 userdata。
thread (线程)
thread 类型用于实现协程(Coroutine),这与操作系统线程不同,协程是协作式的多任务处理。
2.2 字符串详解
字符串的创建与表示
如上所述,可以使用单引号、双引号或长括号创建字符串。
字符串连接
使用 .. 运算符连接两个字符串。如果操作数是数字,Lua 会自动将其转换为字符串。
print("Hello " .. "World") -- Hello World
print(10 .. 20) -- 1020 (注意数字后留空格,防止被解析为小数点)
字符串长度
使用 # 运算符获取字符串的长度(字节数)。
s = "Hello"
print(#s) -- 5
字符串操作
Lua 的 string 库提供了丰富的字符串操作函数。
-
string.upper(s): 转大写
-
string.lower(s): 转小写
-
string.reverse(s): 字符串反转
-
string.format(fmt, …): 格式化字符串,类似于 C 语言的
printf。
s = "Lua"
print(string.upper(s)) -- LUA
print(string.format("Hi %s", s)) -- Hi Lua
print(string.format("Date: %02d/%02d", 1, 2)) -- Date: 01/02
类型转换
-
tonumber(str): 将字符串转换为数字,如果转换失败返回nil。 -
tostring(num): 将数字转换为字符串。
print(tonumber("123") + 1) -- 124
print(tonumber("abc")) -- nil
print(tostring(100) == "100") -- true
2.3 表(Table)基础
表是 Lua 的核心。它本质上是一个关联数组(Associative Array),索引可以是除 nil 以外的任何值。
表的创建与初始化
使用 {} 创建一个空表。
t = {}
t["key"] = "value"
print(t["key"]) -- value
数组风格的表
Lua 中的数组通常以 1 作为起始索引(不同于大多数语言的 0)。
days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}
print(days[1]) -- Sunday
字典风格的表
你可以像操作对象属性一样操作表。
user = {
name = "Alice",
age = 30,
job = "Engineer"
}
print(user.name) -- Alice
print(user["age"]) -- 30
user.name 实际上是 user["name"] 的语法糖。
表的遍历
使用 pairs 遍历字典(键值对),使用 ipairs 遍历数组(数值索引)。
-- 遍历数组
t = {10, 20, 30}
for i, v in ipairs(t) do
print(i, v)
end
-- 输出:
-- 1 10
-- 2 20
-- 3 30
-- 遍历字典
config = {host = "localhost", port = 8080}
for k, v in pairs(config) do
print(k, v)
end
-- 输出 (顺序不保证):
-- host localhost
-- port 8080
练习题
-
定义一个字符串变量,包含你的名字。使用
string.reverse将其反转并打印。 -
创建一个表,存储你喜欢的 3 种水果名称。使用
ipairs遍历并打印它们。 -
创建一个表来描述一本图书,包含
title(标题)、author(作者)和price(价格)。尝试修改价格并打印新的信息。 -
编写代码验证:Lua 中的
0是true还是false?
下一章预告:我们将学习 Lua 的流程控制语句,包括条件判断和各种循环结构,让你的程序具备逻辑处理能力。

