1. Lua 概述
1.1 Lua简介
Lua 是一种由标准 C 语言开发的开源、可扩展的轻量级脚本语言。它最初于 1993 年 由巴西里约热内卢天主教大学的三位研究人员开发,主要用于嵌入式系统和游戏开发。Lua 的设计目标是 简单性 和 灵活性,使其能够轻松集成到其他应用程序中。
核心特点
- 轻量级:Lua 的核心库非常小,适合资源受限的环境。
- 动态类型:变量无需声明类型,类型在运行时自动推断。
- 弱类型:支持隐式类型转换。
- 解释型:通过 Lua 解释器直接执行脚本,无需编译。
- 可扩展性:通过 C/C++ 扩展功能,支持自定义模块。
- 跨平台:支持 Linux、Windows、macOS 等主流操作系统。
- 广泛用途:常用于游戏开发(如 Roblox)、Web 服务器(如 OpenResty)、嵌入式系统等。
Lua 官网
Lua 的官方网站为 https://www.lua.org/,提供源码、文档和社区支持。
1.2 Linux 系统的 Lua
1.2.1 Lua 下载与安装
在 Linux 系统中使用 Lua,需从官网下载源码并编译安装。以下是详细步骤:
下载源码
从官网下载最新版本的 Lua 源码包(如lua-5.4.8.tar.gz
)。解压源码
将源码包上传到 Linux 服务器,并解压到指定目录(如/opt/apps/lua
):tar -zxvf lua-5.4.8.tar.gz -C /opt/apps/
安装 GCC 编译器
Lua 是用 C/C++ 编写的,需要 GCC 编译器支持:sudo apt-get install build-essential
编译与安装
进入解压后的 Lua 目录,执行编译命令:make linux test
编译完成后,安装 Lua:
sudo make install
验证安装
通过以下命令验证 Lua 是否安装成功:lua -v
输出结果应包含 Lua 版本号(如
Lua 5.4.8
)。
1.2.2 输出Hello World
Lua 提供了两种交互模式:命令行模式 和 脚本文件模式。
A. 命令行模式
直接在终端输入 Lua 命令即可运行:
lua
进入 Lua 命令行后,输入以下代码:
print("Hello, World!")
按回车键,输出结果为:
Hello, World!
输入 Ctrl+C
退出命令行模式。
B. 脚本文件模式
创建一个 Lua 脚本文件(如
hello.lua
):print("Hello, World!")
运行脚本文件:
lua hello.lua
可执行文件方式
修改脚本文件为可执行文件:- 在脚本文件顶部添加解释器路径:
#!/usr/bin/lua print("Hello, World!")
- 赋予脚本可执行权限:
chmod +x hello.lua
- 直接运行脚本:
./hello.lua
- 在脚本文件顶部添加解释器路径:
1.3 Windows 系统的 Lua
在 Windows 系统中,最常用的 Lua 环境是 SciTE,它是一个集成了 Lua 编辑器和运行环境的工具。
安装 SciTE
下载地址
SciTE 的官方下载地址为 https://github.com/rjpcomputing/luaforwindows/releases。安装步骤
- 下载安装包(如
LuaForWindows-5.3.5.20170929.exe
)。 - 双击安装包,按照提示完成安装。
- 安装完成后,SciTE 会自动配置 Lua 环境变量。
- 下载安装包(如
运行 Lua 脚本
命令行运行
在 SciTE 中编写脚本后,点击菜单栏的Run > Run
,或按下F5
键运行脚本。调试功能
SciTE 支持断点调试、变量查看等功能,适合初学者学习 Lua 语法。
其他工具
- LuaDist:一个 Lua 包管理工具,简化依赖管理。
- LuaRocks:Lua 的包管理器,类似 Python 的 pip,可安装第三方库。
2. Lua 语法
2.1 Lua 语法基础
2.1.1 注释
Lua 的注释分为两种形式:
行注释:以
--
开头,注释一行内容:-- 这是一个行注释 print("Hello") -- 注释可以跟在代码后
段注释:以
--[[
开始,以--]]
结束,支持多行注释:--[[ 这是一个段注释 可以跨越多行 --]] print("Hello")
技巧:如果需要临时取消段注释,可在开头添加一个 -
,使注释失效:
---[[
print("Hello") -- 此行不会被注释
--]]
2.1.2 数据类型
Lua 有 8 种基础数据类型,通过 type()
函数可查询数据类型:
数据类型 | 描述 |
---|---|
nil |
表示无效值,与 false 类似,但不等同。 |
boolean |
布尔类型,值为 true 或 false 。 |
number |
双精度浮点数类型,支持整数和小数。 |
string |
字符串类型,支持单引号和双引号,可跨行。 |
table |
Lua 的唯一复合数据结构,类似于数组或字典。 |
function |
函数类型,支持匿名函数。 |
thread |
协程(协同线程),用于实现并发。 |
userdata |
用户自定义数据类型,通常通过 C/C++ 扩展使用。 |
示例:
print(type(nil)) --> nil
print(type(true)) --> boolean
print(type(123)) --> number
print(type("Hello")) --> string
print(type({})) --> table
print(type(function() end)) --> function
2.1.3 标识符
程序设计语言中的标识符主要包含保留字、变量、常量、方法名、函数名、类名等。Lua 的标识符由字母、数字与下划线组成,但不能以数字开头。Lua 是大小写敏感的。
(1)保留字
Lua 常见的保留字共有 22 个。不过,除了这 22 个外,Lua 中还定义了很多的内置全局变量,这些内置全局变量的一个共同特征是,以下划线开头后跟全大写字母。所以我们在定义自己的标识符时不能与这些保留字、内置全局变量重复。
and | break | do | else |
---|---|---|---|
elseif | end | false | for |
function | if | in | local |
nil | not | or | repeat |
return | then | true | until |
while | goto |
(2)变量
Lua 是弱类型语言,变量无需类型声明即可直接使用。变量分为全局变量与局部变量。Lua 中的变量默认都是全局变量,即使声明在语句块或函数里。全局变量一旦声明,在当前文件中的任何地方都可访问。局部变量 local 相当于 Java 中的 private 变量,只能在声明的语句块中使用。
(3)动态类型
Lua 是动态类型语言,变量的类型可以随时改变,无需声明。
2.1.4 运算符
Lua 支持多种运算符,包括算术运算符、关系运算符、逻辑运算符等。
A. 算术运算符
运算符 | 描述 | 示例 |
---|---|---|
+ |
加法 | a + b |
- |
减法 | a - b |
* |
乘法 | a * b |
/ |
除法 | 5 / 2 → 2.5 |
% |
取余 | 10 % 3 → 1 |
^ |
乘方 | 2^3 → 8 |
// |
整除(Lua 5.3+) | 5 // 2 → 2 |
注意:
//
仅在 Lua 5.3 及以上版本可用。- SciTE 默认支持 Lua 5.1,需升级环境才能使用新特性。
B. 关系运算符
运算符 | 描述 | 示例 |
---|---|---|
== |
等于 | a == b |
~= |
不等于 | a ~= b |
> |
大于 | a > b |
< |
小于 | a < b |
>= |
大于等于 | a >= b |
<= |
小于等于 | a <= b |
布尔逻辑:
- Lua 将
false
和nil
视为假,其他值(包括0
和空字符串)视为真。
C. 逻辑运算符
运算符 | 描述 | 示例 |
---|---|---|
and |
逻辑与 | a and b |
or |
逻辑或 | a or b |
not |
逻辑非 | not a |
短路特性:
and
:若第一个操作数为假,直接返回第一个操作数。or
:若第一个操作数为真,直接返回第一个操作数。
D. 其他运算符
运算符 | 描述 | 示例 |
---|---|---|
.. |
字符串连接 | "Hello" .. "World" → “HelloWorld” |
# |
获取长度(字符串或表) | #"Hello" → 5 |
2.1.5 函数
Lua 的函数定义以 function
关键字开始,以 end
结束。
A. 固定参数函数
function add(a, b)
return a + b
end
print(add(1, 2)) --> 3
特点:
- 参数数量可变,不足时用
nil
补足,超出部分忽略。
B. 可变参数函数
使用 ...
表示可变参数:
function sum(...)
local args = {...}
local total = 0
for i, v in ipairs(args) do
total = total + v
end
return total
end
print(sum(1, 2, 3)) --> 6
C. 返回多个值
Lua 函数可返回多个值:
function getValues()
return 1, 2, 3
end
local a, b, c = getValues()
print(a, b, c) --> 1 2 3
D. 函数作为参数
Lua 支持将函数作为参数传递:
function apply(func, a, b)
return func(a, b)
end
print(apply(function(x, y) return x + y end, 1, 2)) --> 3
2.1.6 流程控制语句
A. if 条件判断
Lua 的 if
语句语法简洁:
if condition then
-- 条件成立时执行
elseif condition2 then
-- 第二个条件成立时执行
else
-- 所有条件都不成立时执行
end
示例:
local x = 10
if x > 5 then
print("x is greater than 5")
else
print("x is less than or equal to 5")
end
B. if 嵌套
if
语句支持嵌套:
if x > 5 then
if x < 10 then
print("x is between 5 and 10")
end
end
2.1.7 循环控制语句
A. while 循环
local i = 1
while i <= 3 do
print(i)
i = i + 1
end
B. repeat-until 循环
与 while
不同,repeat-until
会先执行循环体,再判断条件:
local i = 1
repeat
print(i)
i = i + 1
until i > 3
C. 数值 for 循环
适用于固定范围的循环:
for i = 1, 3 do
print(i)
end
参数说明:
i
:循环变量。1
:起始值。3
:结束值。- 可选步长:
for i = 1, 10, 2 do ... end
(步长为 2),默认步长为1。
D. 泛型 for 循环
用于遍历 table
,需配合迭代器使用:
local t = {1, 2, 3}
for index, value in ipairs(t) do
print(index, value)
end
E. break 语句
用于提前终止循环:
for i = 1, 10 do
if i == 5 then
break
end
print(i)
end
F. goto 语句
Lua 支持 goto
跳转,但需谨慎使用:
::label::
print("Hello")
goto label -- 无限循环
注意:
- Lua 5.1 不支持
::label::
语法,需升级到 5.3+。
2.2 Lua语法进阶
2.2.1 table
核心概念
table
是 Lua 中唯一的数据结构,既可以表示数组(列表),也可以表示键值对(类似字典/Map),甚至可以混合使用。
1. 数组
特点:
- 索引从
1
开始(默认)。 - 可动态扩展,无需声明长度。
- 支持任意类型元素(包括混合类型)。
- 索引从
示例:
local arr = {10, "Lua", true} print(arr[1]) -- 输出10
2. Map(键值对)
- 定义方式:
- 直接指定键值对:
local map = {name = "张三", age = 23}
- 动态赋值:
local map = {} map["depart"] = "销售部"
- 直接指定键值对:
- 访问方式:
- 通过键直接访问:
map.key
或map[key]
。 - 数组索引方式访问(若键为数字)。
- 通过键直接访问:
3. 混合结构
- 特点:
- 数组索引(数字键)和普通键(字符串或其他)可共存。
- 数组索引不会被普通键占用。
- 示例:
local mixed = {10, 20, name = "混合表"} print(mixed[1]) -- 输出10 print(mixed.name) -- 输出"混合表"
4. table操作函数
函数 | 功能 | 版本限制 |
---|---|---|
table.concat(table, [sep, start, end]) |
连接数组元素为字符串 | 所有版本 |
table.unpack(table, [i, j]) |
拆包(返回数组元素) | Lua5.3+ |
table.pack(...) |
打包(参数转为table) | Lua5.3+ |
table.maxn(table) |
返回最大索引值 | 所有版本 |
table.insert(table, [pos, value]) |
插入元素到指定位置 | 所有版本 |
table.remove(table, [pos]) |
删除并返回指定位置的元素 | 所有版本 |
table.sort(table, [fun(a,b)]) |
排序(升序或自定义规则) | 所有版本 |
示例:
local t = {10, 20, 30}
print(table.concat(t, "-")) -- 输出"10-20-30"
table.insert(t, 40)
table.sort(t)
for i, v in ipairs(t) do print(v) end
2.2.2 迭代器
核心概念
迭代器用于遍历 table
的元素。Lua 提供两种内置迭代器:ipairs
和 pairs
。
1. ipairs
- 功能:仅遍历数组部分(数字索引,且元素非
nil
)。 - 适用场景:顺序遍历数组元素。
- 示例:
local t = {10, 20, 30} for i, v in ipairs(t) do print(i, v) -- 输出1 10, 2 20, 3 30 end
2. pairs
- 功能:遍历整个
table
(包括数组和键值对)。 - 适用场景:需要访问所有键值对时。
- 示例:
local t = {10, 20, name = "Lua"} for k, v in pairs(t) do print(k, v) -- 输出1 10, 2 20, name Lua end
3. 自定义迭代器
- 原理:通过闭包实现状态维护。
- 示例:
function my_iterator(t) local i = 0 return function() i = i + 1 return t[i] end end local t = {10, 20, 30} for v in my_iterator(t) do print(v) -- 输出10, 20, 30 end
2.2.3 模块
核心概念
模块是 Lua 中用于组织和复用代码的机制,类似于其他语言的类库或命名空间。
1. 定义模块
- 文件结构:
- 模块文件通常是一个
.lua
文件,返回一个table
。 - 表中包含模块的函数和变量。
- 模块文件通常是一个
- 示例(文件
mymodule.lua
):local M = {} function M.add(a, b) return a + b end return M
2. 使用模块
- 导入方式:
- 使用
require("模块路径")
导入,可省略小括号,无需.lua
扩展名。
- 使用
- 示例:
local mymodule = require("mymodule") print(mymodule.add(1, 2)) -- 输出3
3. 模块注意事项
- 全局变量污染:模块文件中定义的非
table
变量会成为全局变量。 - 路径问题:
require
会从LUA_PATH
环境变量指定的路径搜索模块。
2.2.4 元表与元方法
元表(Metatable)是 Lua 中用于自定义表行为的核心机制。通过元表,开发者可以扩展表的操作逻辑,例如重载运算符、定义默认行为(如访问不存在的键)或实现自定义的函数调用方式。
1. 重要函数
1.1 setmetatable(table, metatable)
功能:将
metatable
指定为普通表table
的元表。示例:
local t = {10, 20} local mt = {__add = function(a, b) return a.x + b.x end} setmetatable(t, mt)
1.2 getmetatable(table)
功能:获取指定普通表
table
的元表。示例:
local mt = getmetatable(t) print(mt) -- 输出元表内容
2. 核心元方法
2.1 __index
元方法
触发条件:当访问表中不存在的键时触发。
功能:
- 可以是一个函数:返回自定义值。
- 可以是另一个表:从该表中查找键。
示例:
-- 返回自定义值的情况 local mt = { __index = function(tab, key) return "未知的键: " .. key end } local t = {x = 10} setmetatable(t, mt) print(t.y) -- 输出 "未知的键: y" -- 从另一个表中查找键的情况 local mt = { __index = {y = 20} } local t = {x = 10} setmetatable(t, mt) print(t.y) -- 输出 20
2.2 __newindex
元方法
- 触发条件:当向表中不存在的键赋值时触发。
- 功能:
- 可以是一个函数:控制赋值逻辑。
- 可以是另一个表:将键值对存储到该表中。
- 示例:
-- 控制赋值逻辑 local mt = { __newindex = function(tab, key, value) print("新增键:", key, "值:", value) rawset(tab, key, value) -- 手动赋值 end } local t = {x = 10} setmetatable(t, mt) t.y = 20 -- 输出 "新增键: y 值: 20" -- 将键值对存储到另一个表中 local mt = { __newindex = {y = 30} } local t = {x = 10} setmetatable(t, mt) t.y = 20 -- 存储到 mt.__newindex 表中 print(t.y) -- 输出 nil(因为未修改原始表) print(mt.__newindex.y) -- 输出 20
3. 运算符元方法
通过重写运算符元方法,可以自定义表的运算行为。
3.1 常见运算符元方法
元方法 | 运算符 | 功能说明 |
---|---|---|
__add |
+ |
加法操作 |
__sub |
- |
减法操作 |
__mul |
* |
乘法操作 |
__div |
/ |
除法操作 |
__mod |
% |
取模操作 |
__pow |
^ |
幂运算 |
__unm |
- |
取反操作 |
__eq |
== |
相等性比较 |
__lt |
< |
小于比较 |
__le |
<= |
小于等于比较 |
__concat |
.. |
字符串连接 |
__len |
# |
获取表长度 |
__tostring |
tostring |
自定义字符串表示 |
__call |
() |
将表作为函数调用 |
3.2 示例:自定义加法运算
local mt = {
__add = function(a, b)
return a.x + b.x
end
}
local t1 = {x = 10}
local t2 = {x = 20}
setmetatable(t1, mt)
print(t1 + t2) -- 输出 30
4. __tostring
元方法
直接输出一个table,其输出内容为类型为table的存放地址,如果想让其输出table中的内容,可重写__tostring方法。
- 功能:自定义表的字符串表示。
- 示例:
local mt = { __tostring = function(t) local str = "{ " for k, v in pairs(t) do str = str .. k .. "=" .. v .. ", " end return str .. "}" end } local t = {x = 10, y = 20} setmetatable(t, mt) print(t) -- 输出 { x=10, y=20, }
5. __call
元方法
- 功能:将表作为函数调用。
- 示例:
local mt = { __call = function(t, num, str) for k, v in pairs(t) do if type(v) == "number" then t[k] = v + num elseif type(v) == "string" then t[k] = v .. str end end return t end } local t = {x = 10, y = "Hello"} setmetatable(t, mt) local newT = t(5, "-world") for k, v in pairs(newT) do print(k, v) -- 输出 x=15, y=Hello-world end
6. 元表的高级应用
6.1 模拟类继承
通过 __index
实现类似类继承的逻辑:
-- 父类
local Parent = {x = 10}
-- 子类
local Child = {y = 20}
-- 设置子类的元表,指向父类
setmetatable(Child, {__index = Parent})
print(Child.x) -- 输出 10(继承自 Parent)
print(Child.y) -- 输出 20
6.2 自定义错误提示
当访问不存在的键时,返回自定义错误信息:
local mt = {
__index = function(t, key)
error("键 " .. key .. " 不存在")
end
}
local t = {x = 10}
setmetatable(t, mt)
print(t.y) -- 抛出错误:键 y 不存在
7. 元表的单独定义
为了便于复用,可以将元表定义为单独的模块文件。
7.1 定义元表文件(my_metatable.lua
)
local mt = {}
mt.__index = function(t, key)
return "默认值: " .. key
end
return mt
7.2 使用元表文件
local mt = require("my_metatable")
local t = {x = 10}
setmetatable(t, mt)
print(t.y) -- 输出 "默认值: y"
总结
元表是 Lua 中实现自定义行为的强大工具。通过合理使用 __index
、__newindex
、运算符元方法等,可以扩展表的功能,实现类继承、自定义操作符甚至更复杂的逻辑。掌握元表的使用,能够显著提升 Lua 代码的灵活性和可维护性。
2.3 Lua模拟面向对象
Lua 中没有显式的类(class)概念,但通过 table
、function
和元表(metatable)可以模拟类的功能。
2.3.1 简单对象的创建
通过 table
和 function
可以创建一个简单的对象。
定义对象
- 属性:通过
table
的键值对存储。 - 行为:通过
function
赋予对象的方法。
示例代码:
-- 创建一个简单对象
local person = {
name = "张三",
age = 22,
sayHello = function(self)
print("你好,我是" .. self.name)
end
}
person:sayHello() -- 输出"你好,我是张三"
2.3.2 类的创建
通过 table
、function
和元表可以定义类,并支持继承。
1 定义基础类
new()
方法:用于创建类的实例。- 元表:通过
__index
实现继承。
示例代码:
-- 定义基础类 Person
local Person = {}
function Person:new(name, age)
local obj = {name = name, age = age}
setmetatable(obj, {__index = self}) -- 设置元表,实现继承
return obj
end
function Person:sayHello()
print("你好,我是" .. self.name)
end
-- 创建对象
local p1 = Person:new("张三", 23)
p1:sayHello() -- 输出"你好,我是张三"
2 类的继承
通过元表的 __index
实现子类继承父类的属性和方法。
示例代码:
-- 定义子类 Student 继承自 Person
local Student = {}
Student.__index = Student
-- 设置 Student 的元表为 Person
setmetatable(Student, {__index = Person})
function Student:new(name, age, studentId)
local obj = Person:new(name, age) -- 调用父类构造函数
obj.studentId = studentId
setmetatable(obj, self) -- 设置元表
return obj
end
function Student:study()
print(self.name .. "正在学习")
end
-- 创建 Student 对象
local s1 = Student:new("李四", 20, "S001")
s1:sayHello() -- 输出"你好,我是李四"
s1:study() -- 输出"李四正在学习"
2.3.3 静态方法与私有变量
通过闭包和模块化设计可以实现静态方法和私有变量。
1 静态方法
- 定义方式:直接定义在类表中,不依赖实例。
示例代码:
-- 定义静态方法
Person.getDescription = function()
return "这是一个Person类"
end
print(Person.getDescription()) -- 输出"这是一个Person类"
2 私有变量
- 实现方式:通过闭包保护变量,仅允许类内部访问。
示例代码:
-- 使用闭包实现私有变量
local Person = {}
local privateData = {} -- 私有变量
function Person:new(name)
local obj = {name = name}
privateData[obj] = {secret = "这是私有数据"} -- 存储私有数据
setmetatable(obj, self)
self.__index = self
return obj
end
function Person:getSecret()
return privateData[self].secret -- 访问私有数据
end
local p1 = Person:new("王五")
print(p1:getSecret()) -- 输出"这是私有数据"
-- print(privateData.p1.secret) -- 报错,无法直接访问私有数据
2.3.4 多继承
通过元表的 __index
可以实现多继承(继承多个类的属性和方法)。
示例代码:
-- 定义类 A
local A = {}
function A:sayA()
print("这是类A的方法")
end
-- 定义类 B
local B = {}
function B:sayB()
print("这是类B的方法")
end
-- 定义类 C,继承 A 和 B
local C = {}
setmetatable(C, {__index = A}) -- 继承 A
C.__index = C
function C:new()
local obj = {}
setmetatable(obj, self)
return obj
end
-- 将 B 的方法复制到 C 中(模拟多继承)
for k, v in pairs(B) do
C[k] = v
end
local c = C:new()
c:sayA() -- 输出"这是类A的方法"
c:sayB() -- 输出"这是类B的方法"
2.4 协同线程与协同函数
协同线程(coroutine)是 Lua 中的一种轻量级线程,允许程序在运行过程中暂停和恢复。
2.4.1 协同线程的基本操作
1 创建协同线程
coroutine.create(f)
:创建一个协同线程实例。
示例代码:
local co = coroutine.create(function()
print("协同线程开始")
end)
2 启动协同线程
coroutine.resume(co)
:启动或恢复协同线程的执行。
示例代码:
coroutine.resume(co) -- 输出"协同线程开始"
3 挂起协同线程
coroutine.yield()
:暂停当前协同线程的执行。
示例代码:
local co = coroutine.create(function()
print("第一段")
coroutine.yield() -- 挂起
print("第二段")
end)
coroutine.resume(co) -- 输出"第一段"
coroutine.resume(co) -- 输出"第二段"
4 查看协同线程状态
coroutine.status(co)
:返回协同线程的状态(running
、suspended
、dead
)。
示例代码:
print(coroutine.status(co)) -- 输出"dead"
5 关闭协同线程
coroutine.close(co)
:强制关闭协同线程。
示例代码:
coroutine.close(co)
2.4.2 协同函数
通过 coroutine.wrap(f)
可以创建协同函数,其调用会启动一个协同线程。
示例代码:
local coFunc = coroutine.wrap(function()
print("协同函数开始")
coroutine.yield()
print("协同函数结束")
end)
coFunc() -- 输出"协同函数开始"
coFunc() -- 输出"协同函数结束"
2.4.3 协同线程的应用场景
1 生成器模式
协同线程可以作为生成器,逐次返回数据。
示例代码:
function generator()
for i = 1, 3 do
coroutine.yield(i * 10)
end
end
local co = coroutine.create(generator)
coroutine.resume(co)
while true do
local status, value = coroutine.resume(co)
if not status then break end
print(value) -- 依次输出10, 20, 30
end
2 状态机
协同线程可以用于实现状态机,逐步执行不同状态逻辑。
示例代码:
local stateMachine = coroutine.create(function()
print("状态1")
coroutine.yield()
print("状态2")
coroutine.yield()
print("状态3")
end)
coroutine.resume(stateMachine) -- 输出"状态1"
coroutine.resume(stateMachine) -- 输出"状态2"
coroutine.resume(stateMachine) -- 输出"状态3"
2.5 文件 IO
Lua 提供了丰富的文件 IO 操作函数,分为静态函数和实例函数。
2.5.1 静态函数
1 io.open(filename, mode)
- 功能:打开文件并返回文件句柄。
- 模式说明:
r
:只读(默认)。w
:只写(覆盖原有内容)。a
:追加写入。+
:与r
、w
、a
结合使用,表示读写模式。b
:二进制模式。
示例代码:
local file = io.open("example.txt", "w")
file:write("Hello, Lua!\n")
file:close()
2 io.input(file)
- 功能:设置默认输入文件。
示例代码:
io.input("example.txt")
local content = io.read("*a") -- 读取整个文件内容
print(content) -- 输出"Hello, Lua!"
3 io.output(file)
- 功能:设置默认输出文件。
示例代码:
io.output("output.txt")
io.write("写入内容\n")
io.close()
2.5.2 实例函数
1 file:read([format])
- 功能:从文件中读取数据。
- 格式说明:
*l
:读取一行(默认)。*n
:读取一个数字。*a
:读取整个文件。number
:读取指定字符数。
示例代码:
local file = io.open("example.txt", "r")
local line1 = file:read("*l") -- 读取第一行
local line2 = file:read("*l") -- 读取第二行
file:close()
print(line1, line2)
2 file:write(data)
- 功能:将数据写入文件。
示例代码:
local file = io.open("example.txt", "a")
file:write("追加内容\n")
file:close()
3 file:seek([whence, offset])
- 功能:设置或获取文件指针位置。
- 参数说明:
set
:定位到文件开头(默认)。cur
:相对于当前位置。end
:定位到文件末尾。
示例代码:
local file = io.open("example.txt", "r+")
file:seek("set", 0) -- 定位到文件开头
file:write("新内容")
file:close()
文件操作的完整示例示例代码:
-- 写入文件
local file = io.open("data.txt", "w")
file:write("第一行\n")
file:write("第二行\n")
file:close()
-- 读取文件
file = io.open("data.txt", "r")
print("读取文件内容:")
for line in file:lines() do
print(line) -- 依次输出"第一行"、"第二行"
end
file:close()
暂时结束。