基本语法与数据类型

2.1 程序结构

语句分隔符

Lua 中分号 ; 是可选的。同一行写多条语句时推荐加分号,否则通常省略:

1
2
3
4
5
6
7
8
9
10
-- 不写分号
a = 1
b = 2

-- 同一行写多条语句
c = 3; d = 4

-- 换行即分隔,不需要分号
x = 10
y = 20

空白与缩进

Lua 忽略多余的空格和空行,但为了代码可读性,建议使用 2 个空格一个 Tab 缩进:

1
2
3
4
5
6
if x > 0 then
print("正数")
if x > 100 then
print("大数")
end
end

代码块 do...end

do...end 用于创建一个显式的作用域块:

1
2
3
4
5
do
local x = 10
print(x) -- 10
end
print(x) -- nil,因为 x 在块外不可见

2.2 注释

单行注释

使用两个连续的减号 --

1
2
-- 这是一个单行注释
print("Hello") -- 行末注释

多行注释

使用 --[[]]

1
2
3
4
5
6
7
--[[
这是一个多行注释
可以跨越多行
非常方便
]]

print("注释结束")

注释技巧:启用/禁用代码块

1
2
3
4
5
6
7
8
9
--[[
print("这行被注释了")
print("这行也被注释了")
--]]

---[[
print("在第一行加一个 -,变成 ---[[,注释就被取消了")
print("这是一个常用的开关技巧")
--]]

2.3 标识符与关键字

标识符命名规则

  • 以字母或下划线开头
  • 后面跟字母、数字、下划线
  • 区分大小写(nameNameNAME 是三个不同的变量)
  • 建议不使用 _ 开头的标识符(Lua 内部使用习惯)
1
2
3
4
5
6
7
8
9
10
-- 合法的标识符
name = "Lua"
_name = "私有"
name2 = "带数字"
myVarName = "驼峰"

-- 不合法的标识符
-- 2name = "数字开头" -- 错误
-- my-name = "连接符" -- 错误
-- function = "关键字" -- 错误

Lua 保留关键字(21 个)

1
2
3
4
5
and       break     do        else      elseif
end false for function goto
if in local nil not
or repeat return then true
until while

关键字不能用作标识符。


2.4 数据类型概览

Lua 中有 8 种基本类型

类型 名称 示例值
nil nil
boolean 布尔 true, false
number 数字 42, 3.14, -5
string 字符串 "hello", 'world'
table {1, 2, 3}
function 函数 function() end
userdata 用户数据 C 创建的数据
thread 线程 协程

使用 type() 函数查看值的类型:

1
2
3
4
5
6
7
8
9
print(type(nil))        --> nil
print(type(true)) --> boolean
print(type(42)) --> number
print(type(3.14)) --> number
print(type("hello")) --> string
print(type({})) --> table
print(type(print)) --> function
print(type(type)) --> function
print(type(coroutine.create(function() end))) --> thread

2.5 各类型详解

nil(空)

nil 表示”没有有效值”,用于:

  • 变量未赋值时默认值为 nil
  • 删除表的元素:t.key = nil
  • 表示逻辑假(在条件判断中 nil 等同于 false
1
2
3
4
5
6
7
8
local x
print(x) --> nil

x = 100
print(x) --> 100

x = nil -- 清除变量
print(x) --> nil

boolean(布尔)

只有 truefalse 两个值。注意:在 Lua 中,nilfalse 为假,其他所有值都为真(包括 0 和空字符串)。

1
2
3
4
5
print(true and false)  --> false
print(false or nil) --> nil
print(not true) --> false
print(not 0) --> false(0 为真)
print(not "") --> false(空字符串也为真)

number(数字)

Lua 默认使用双精度浮点数(64 位),在 Lua 5.3 之后引入了整数子类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-- 都是 number 类型
print(type(42)) --> number
print(type(3.14159)) --> number
print(type(-10)) --> number

-- 科学计数法
print(1e3) --> 1000.0
print(1.5e-2) --> 0.015

-- 十六进制(Lua 5.2+)
print(0xFF) --> 255
print(0x1A) --> 26

-- 整数除法 //(Lua 5.3+)
print(10 / 3) --> 3.3333333333333
print(10 // 3) --> 3(整除)
print(-10 // 3) --> -4(向下取整)

string(字符串)

字符串用单引号、双引号或长括号包裹:

1
2
3
4
5
6
7
8
9
10
11
12
13
s1 = "双引号"
s2 = '单引号'
s3 = [[
长括号
支持换行
]]

-- 字符串连接用 ..
print("Hello" .. " " .. "World") --> Hello World

-- 字符串长度
print(#"hello") --> 5
print(#s3) --> 包含换行符的长度

table(表)

表是 Lua 最强大、最灵活的数据结构,用花括号 {} 创建:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- 空表
t = {}

-- 数组风格(索引从 1 开始)
arr = {"a", "b", "c"}
print(arr[1]) --> a
print(arr[3]) --> c

-- 字典风格
dict = {name = "Lua", version = "5.4"}
print(dict.name) --> Lua
print(dict["version"]) --> 5.4

-- 混合风格
mix = {1, 2, key = "value", [100] = "hundred"}

后面有专门章节深入讲解 table。

function(函数)

函数是第一类值,可以赋给变量、存入表、作为参数传递:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- 具名函数
function add(a, b)
return a + b
end

-- 匿名函数赋值给变量
local multiply = function(a, b)
return a * b
end

-- 函数作为参数
function apply(f, a, b)
return f(a, b)
end
print(apply(add, 3, 4)) --> 7

userdata 和 thread

  • userdata:用于存储 C 语言创建的数据,Lua 代码不能直接修改,只能通过 C API 操作
  • thread:用于协程(coroutine),在第 08 章会讲到

2.6 type() 函数

type() 返回一个描述数据类型的字符串

1
2
3
local t = type(42)
print(t) --> number
print(type(t)) --> string(因为 t 本身是字符串)

2.7 本章小结

  • 分号可选,换行即语句分隔
  • do...end 创建代码块
  • -- 单行注释,--[[ ]] 多行注释
  • 8 种数据类型:nilbooleannumberstringtablefunctionuserdatathread
  • type() 返回类型的字符串名称
  • 在条件判断中,只有 nilfalse 为假

练习题

  1. 使用 type() 打印 niltrue0""(空字符串)、{} 的类型
  2. 验证 0"" 在条件判断中是否为真
  3. 尝试在交互式模式中访问一个不存在的变量,观察返回什么
  4. 声明一个局部变量,在 do...end 块外访问它,观察结果
ByteFisher
分享编程技术 · 记录钓鱼乐趣
扫码关注
▸ 扫码关注 ◂
Lua基础教程 系列
第 2/15 篇
分享: