Lua学习笔记(基础入门)

简介

  1. lua是一个轻量小巧的脚本语言,编译后一百多K
  2. 用标准C编写
  3. 以源码形式发布
  4. 设计目标是为了嵌入其他程序
  5. 支持面向对象
  6. 自动内存管理
  7. 可以扩展其他软件的能力,如nginx(openresty)

环境安装

mac

1
$ brew install lua

执行

1
$ lua test.lua

基本语法

注释

单行

1
-- 单行注释

多行

1
2
3
--[[
多行注释
--]]

标识符

  1. 大小写字母 + 数字 + 下划线
  2. 数字不开头
  3. 不允许$
  4. 区分大小写
  5. 不建议使用下划线和大写字母组合,与lua保留字规则相同

全局变量

  1. 不加任何关键字修饰的变量为为全局变量
  2. 访问没有初始化的全局变量返回nil

8种数据类型

判断数据类型

1
print(type("123"))
  1. nil,表示一个无效值,条件表达式中相当于false,将变量或者table中key赋值为nil相当于删除,type(nil)返回’nil’字符串
  2. boolean,true or false,false和nil为假,其他为真
  3. number,双精度浮点数,lua只有双精度,
  4. string,单引号或者双引号的字符串,也可以使用[[]]表示多行字符串
  5. function,C或者lua编写的函数,支持匿名函数
  6. userdata,表示任意存储在变量中的C数据结构,如struct、指针
  7. thread,执行的独立线路,用于执行协同
  8. table,表,其实是一个关联数组,索引可以是数字或者字符串。通过{}创建或者初始化。

线程跟协程的区别:

线程可以同时多个运行,而协程任意时刻只能运行一个,并且处于运行状态的协程只有被挂起(suspend)时才会暂停。

变量

全局变量:不使用任何修饰符声明,无论在哪里声明都是全局变量

局部变量:使用local声明,作用域为当前语句块

变量赋值:

1
2
3
4
5
6
a = b

a,b = c,d

-- 直接交换,不需要第三个变量
a, b = b, a

table操作:

  1. 支持点(.)操作符
  2. 支持方括号([])

流程控制

循环

跳出循环: break

1
2
3
4
while(condition)
do
-- do something
end
1
2
3
4
-- 从1到10,步长为1
for i=1,10,1 do
print(i)
end
1
2
3
4
5
-- ipairs是一个迭代器,用于迭代数组
a = {"one", "two", "three"}
for i, v in ipairs(a) do
print(i, v)
end
1
2
3
4
-- 相当于do while
repeat
-- do something
until(condition)

循环可以嵌套使用

条件语句
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
if(condition)
then
-- do something
end

if(condition)
then
-- do something
else
-- do something
end

if(condition)
then
-- do something
elseif(condition)
then
-- do something
else
-- do something
end

函数

格式
1
2
3
4
5
6
function_scope function function_name( argument list)

function_body

return result
end
  1. function_scope,函数作用域,可选,默认全局,可以用local声明局部函数
  2. 返回值可以是多个值,用逗号分隔
(数量)可变参数
  1. 可以使用...标识函数有可变参数
  2. 可以使用select("#",...)获取可变参数数量
  3. 同其他语言一样,可变参数必须在参数列表最后
  4. 可使用select(n, …)直接访问第n个参数
1
2
3
function fwrite(fmt, ...)
return io.write(string.format(fmt, ...))
end

运算符

算数运算符
  1. +,加
  2. -,减
  3. *,乘
  4. /,除
  5. %,取余
  6. ^,幂乘
  7. -,负号
关系运算符
  1. ==,等于
  2. ~=,不等于
  3. >,大于
  4. <,小于
  5. >=,大于等于
  6. <=,小于等于
逻辑运算符
  1. and,逻辑与
  2. or,逻辑或
  3. not,逻辑非
其他
  1. ..,连接两个字符串
  2. #,返回字符串或者表的长度

字符串

常用函数
  1. string.upper,转大写
  2. string.lower,转小写
  3. string.gsub(maiString, findString, replaceString, num),将第一参数的字符串中的第二参数替换为第三参数,第四参数是替换几次,默认全替换。返回值为新字符串和替换次数
  4. string.find(str, subStr, start, end),在str中找subStr的位置,三四参数为起始结束位置,可选。返回值为起始和结束位置。
  5. string.reverse,字符串顺序调换
  6. string.format,类似C,支持%d、%c、%o、%s等占位符
  7. string.char(argList),将数字转字符
  8. string.byte(arg, int),见字符串转数字,第二参数可选
  9. string.len,字符串长度
  10. string.rep(arg, n),将第以参数的字符串重复n次
  11. ..,连接两个字符串
  12. string.gmatch(str, pattern),返回迭代器函数,每次调用返回下一匹配到的结果,没有返回nil
  13. string.match(str, pattern, init),与gmatch类似,不过只查找第一次匹配,第三参数是起始位置
模式匹配

类似于正则

数组

  1. 数组下标为数字
  2. 长度不固定
  3. 支持多维的情况,其实是数组元素的引用关系
1
2
3
4
5
array = {"Lua", "Tutorial"}

for i= 0, 2 do
print(array[i])
end

迭代器

支持指针类型的结构

1
2
3
4
5
6
7
8
9
10
11
-- demo 1
for k, v in pairs(t) do
print(k, v)
end

-- demo 2
array = {"Lua", "Tutorial"}
for key,value in ipairs(array)
do
print(key, value)
end
无状态迭代器

待补充

多状态迭代器

待补充

table

  1. lua的数组 + 字典
  2. key可以是除nil外的任何类型
  3. 大小不固定
1
2
3
4
5
6
7
8
-- 初始化表
mytable = {}

-- 给指定key赋值
mytable[1]= "Lua"

-- 删除,垃圾回收会释放内存
mytable = nil
table操作
  1. table.concat,将table中的元素连接起来
  2. table.insert(table, [pos,] value),在指定位置插入元素,不指定位置则插入到末尾
  3. table.remove(table, [,pos]),删除指定位置的元素,不指定位置则删除最会后一个
  4. table.sort,按照升序排序

模块与包

  1. 从5.1开始加入模块管理机制
  2. 定义一个模块返回一个table即可
定义模块示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
-- 文件名为 module.lua
-- 定义一个名为 module 的模块
module = {}

-- 定义一个常量
module.constant = "这是一个常量"

-- 定义一个函数
function module.func1()
io.write("这是一个公有函数!\n")
end

local function func2()
print("这是一个私有函数!")
end

function module.func3()
func2()
end

return module
模块导入
1
2
3
4
5
6
7
8
local module = require('模块名')
-- 或者
local module = require '模块名'

-- 示例
local module = require("module")
print(module.constant)
module.func3()
加载机制
  1. 从环境变量LUA_PATH指定的目录加载模块
  2. LUA_PATH以分号;分割
  3. LUA_PATH结尾的双分号;;表示不要清空原有的LUA_PATH,而且将两个LUA_PATH做拼接
  4. 如果找到lua文件在加载
  5. 如果找不到lua文件尝试加载C程序库
  6. C程序库按照环境变量LUA_CPATH指定的路径查找,搜索的文件为so或者dll

元表(Metatable)

lua的元编程,类似其他语言的云算法重载,针对table。

待补充

协同

  1. 线程与协同程序的主要区别在于,一个具有多个线程的程序可以同时运行几个线程,而协同程序却需要彼此协作的运行。
  2. 在任一指定时刻只有一个协同程序在运行,并且这个正在运行的协同程序只有在明确的被要求挂起的时候才会被挂起。
  3. 协同程序有点类似同步的多线程,在等待同一个线程锁的几个线程有点类似协同。
  4. 底层用线程实现
  5. 解决与生产者消费者类似的问题
主要方法
  1. coroutine.create(),接收函数,返回协同
  2. coroutine.resume(),将挂起的协同恢复执行状态
  3. coroutine.yield(),挂起协同
  4. coroutine.status(),返回协同状态
  5. coroutine.wrap(),与create类似
  6. coroutine.running(),返回正在执行的协同

I/O

格式

local file = io.open(filename[, mode])

mode可选值

  1. r,只读,文件必须存在
  2. w,只写,会清空文件内容
  3. a,只写拼接,在文件后新增
  4. r+,读写,文件必须存在
  5. w+,读写,会清空文件内容
  6. a+,读写拼接,在文件后新增
  7. b,二进制模式,当操作二进制文件时使用
  8. +,即可读也可写

file:read参数

  1. *n
  2. *a,读取全部
  3. *l,读取下一行,默认行为
  4. number,读取number个

示例

1
2
3
4
5
local file = io.open("test.lua", "r")
print(file:read())
file:write(' content ')
file:flush()
file:close()

垃圾回收

lua自动分配内存,自动回收垃圾,但是程序员预留了干预垃圾回收行为的函数collectgarbage,可以通过该函数微调垃圾回收行为,甚至可以停止自动垃圾回收。

推荐文章