前言(Programming in Lua(4th) 内容基于 Lua 5.3)
虽然在某些方面 Lua 与其他语言有着共同的特色,但下面这些特征是 Lua 特有的:
1. 可扩展;2. 简明;3. 高效;4. 可移植
Lua 使用者分为三大类:
1. 在应用中嵌入地使用;2. 单独使用 ;3. 和 C 一起使用。
官方网站:http://www.lua.o
用户社区:http://lua-users.org
第1章 Lua语言入门
Chunk (程序段)是一组命令或表达式组成的序列。
在prog.lua中第一行加入#!/usr/bin/lua,则可以直接执行:$ ./prog
使用- i 参数可以让 Lua 语言解释器在执行完指定的程序段后进入交互模式: lua -i prog.lua
在交互模式下运行 dofile("prog.lua") ,该函数会立即执行prog.lua
-e 参数允许我们直接在命令行中输入代码 $ lua -e "print("hello")"
第3章 数值
Lua从 5.3 开始支持64位整型和双精度(最大值 2^53)浮点型。编译为精简Lua模式,则支持32位整型和单精度浮点型。在 Lua 5.2 及之前的版本中,所有的数值都以双精度浮点格式表示 。
type(3)和type(3.0)都是"number",-3 == -3.0结果是true。
math.type(3) 返回 integer,math.type(3.0)返回float。由此可区分整型和双精度
如果两个操作数都是整型值,那么结果也是整型值;否则,结果就是浮点型值。
但是除法运算操作的结果永远是浮点数。Lua 5.3 针对整数除法引入了一个称为floor 除法的新算术运算符“//”,从而保证结果是一个整数 。幂运算(^)结果是浮点数。
数学库math含有:三角函数、指数函数、取整函数、max、min、floor、ceil、random、pi和huge(大多数平台上代表inf)。
第4章 字符串
字符串用于表示文本,Lua 语言中的字符串是不可变值( immutable value)。
使用单引号声明字符串,双引号不用转义; 使用双引号声明字符串,单引号不用转义。
多行字符串可用 [==[ 和 ]==] 声明,其中等号数量>=0。注释类似:-- [==[ 和 ]==] 。
转义序列 z 会使字符串跳过其后的所有空白字符,直到遇到第一个非空白字符。
第5章 表
表是Lua 语言中最主要(事实上也是唯一的)和强大的数据结构。
当被用作表索引时,任何能够被转换为整型的浮点数都会被转换成整型数 。例如,当执行表达式 a[2.0]=10 时,键 2.0 会被转换为 2 。
通用构造器:
--通过方括号括起来的表达式显式地指定每一个索引, --从而能使用负数索引,也能使用普通构造器不能使用的标识符作为索引 opnames = {["+"] = "add", ["-"] = "sub", ["*"] = "mul", ["/"] = "div"} i = 20; s = "-" a = {[i + 0] = s, [i + 1] = s..s, [i + 2] = s..s..s} print(opnames[s]) -- > sub print(a[22]) -- > ---
--使用 pairs 迭代器遍历表中的键值对, 遍历过程中元素的出现顺序可能是随机的, --相同的程序在每次运行时也可能产生不同的顺序。 --对于列表而言,可以使用 ipairs。此时,Lua会确保遍历是按照顺序进行的。 t = {10, print, x = 12, k = "hi"} for k, v in pairs(t) do print(k, v) end
安全访问
local a = {x = {y = {z = 10}}} local r = (((a or {}).x or {}).y).z print(r) --10 r = (((a or {}).x or {}).y).x print(r) --nil
第6章 函数
第7章 输入输出
--可以使用函数 io.open 来打开一个文件,然后使用方法 read 和 write 从流中读取和向流中写入。 local filename = "test.lua" local f = io.open(filename, "r") local t = f:read("a") print(t) f:close()
local message = "error message: ... " io.stderr:write(message)
函数 io.input 和 io.output 允许混用完整 I/O 模型和简单 I/O 模型
local temp = io.input() -- 保存当前输入流 io.input("test.lua") -- 打开一个新的当前输入流 -- 对新的输入流进行某些操作 print(io.input():read("l")) print(io.read("l")) -- 作用同上一行 io.input():close() -- 关闭当前流 io.input(temp) -- 恢复此前的当前输入流 io.input():close() -- 关闭当前流
获取和设置当前位置
function fsize (file) local current = file:seek() -- 保存当前位置 local size = file:seek("end") -- 获取文件大小 file:seek("set", current) -- 恢复当前位置 return size end local filename = "test.lua" local f = io.open(filename, "a") f:seek("end") -- 定位到文件尾 f:setvbuf("full") -- 设置全缓冲,其他(full/no/line) f:write(" --append content") f:flush() --刷新流f --append content
其他系统调用:
print(os.getenv ("HOME")) -- > /home/lua os.execute("ls") --同函数 os.execute 一样,popen运行一条系统命令 --但该函数还可以重定向命令的输入/输出 local f = io.popen ("ls .", "r") for entry in f:lines() do print(entry) end os.exit(0)
第8章 补充知识
1 local a = {1, 2, 3, 4} 2 local i = 1 3 while a[i] do 4 if a[i] == 2 then 5 i = i + 1 6 goto continue --跳到了变量var的作用域外 7 end 8 print(a[i]) 9 i = i + 1 10 local var = 8 11 ::continue:: 12 --print(var) -- <goto continue> at line 6 jumps into the scope of local 'var' 13 --print(i) -- <goto continue> at line 6 jumps into the scope of local 'var' 14 end 15 16 --代码块中的标签对外不可见 17 --goto continue -- no visible label 'continue' for <goto> at line 17