wqiaofujiang 2020-01-02
Mac 上也可以通过 homebrew 安装,便于版本管理。
brew install lua
lua-基础语法
-- 注释
-- [[]] -- 多行注释, 如果临时取消多行注释,只需要在头部"--" 改为 "---"即可
下划线加大写字母为关键字
变量缺省为nil,删除变量给其赋值nil即可
交互式编程&脚本式编程(执行式脚本要加解释器-#!/usr/local/bin/lua), 通过 Ctrl+D(发送退出信号),Ctrl+C(强制中断)退出;或通过 os.exit()退出
lua-数据类型
nil -- 没有任何有效值,只有一个值nil
boolean -- true、false(nil)
number -- double双精度
string -- 单引号或双引号, 也可以使用[[]], 允许数字字符串 与数字相加,能够自动转换类型
table -- 通过构建表达式进行创建, {} 或者 {"a":"b"}等, 可缺省键,默认从1开始(不是从0开始)
table遍历
local tbl = {"apple", "pear", "orange", "grape"}
for key, val in pairs(tbl) do
print(key .. " : " .. val)
end
pair 和 ipair区别: pair遍历所有键值对,ipair固定的从key值1开始,下次key值累加1进行遍历,如果key对应value不存在,就停止遍历
table元素个数表示方法: #tb
function --函数可以存在变量里,函数可以作为参数进行传递(匿名函数)
thread --主要是协同线程,其他线程可以同时多个运行,协同线程任意时刻只能运行一个,处于运行状态的协程只有被挂起才会暂停
userdata -- 用户自定义数据
type(变量) --查看类型, type 返回值为string类型
lua-变量
全局变量:默认是全局变量
局部变量:用local显式声明,作用域从声明开始到语句块结束
表中的域:
变量默认值为nil
赋值
x, y = y, x --遇到赋值语句lua会先计算右边所有值后再执行赋值操作
多值赋值经常用来交换变量,或将函数调用返回给变量
table[‘key‘] == table.key --和node类似
lua-循环
while do end、for do end; 不能使用continue
for i = 1,10,1 do print(i) end
for i,v in pairs(t) do ... end
lua-流程控制
if then else end. --if里只要不是false、nil,都是true
lua-函数
完成指定的功能-调用;计算返回值-赋值
--函数可以作为参数进行传递
--函数可以返回多个值
--支持变长参数,参数形态:(...)
--获取边长参数方法
function foo(...)
for i = 1, select(‘#‘, ...) do -->获取参数总数
local arg = select(i, ...); -->读取参数
print("arg", arg);
end
end
foo(1, 2, 3, 4);
lua-运算符
-- ~= 不等
--逻辑运算符 and or not, 与mysql相似,与java不同
-- # 一元运算符, 返回字符串或表的长度;
-----针对table来说,如果数组中有一个空洞(即nil值被夹在非空值之间),那么#可能指向任何一个是nil值的前一个位置下标
-----#找的是表的最大索引下标值
-- .. 连接运算符
-- 三目运算符: condition * and * or *
lua-字符串
string.upper
string.lower
string.gsub --替换
string.reverse
string.find
string.format() --格式化
string.char --将整数值转换为字符
string.byte --将字符转换为整数值
string.len
string.rep
string.gmatch
string.match
lua-数组
数组设置了指定的索引值, 避免出现nil
for i, j, n do ... end
lua-迭代器
for k, v in pairs(t) do
...
end
lua-迭代器
pairs 迭代table,可以遍历表中所有的key,可以返回nil
ipairs 迭代数组, 不能返回nil, 如果遇到nil则会出
lua-table
table.concat
table.insert
table.remove
table.sort
lua-模块与包
lua模块由变量、函数等已知元素组成table,创建一个模块,就是创建一个table
require函数用来加载模块
lua-metatable
--解决痛点:可以同时对多个表进行操作,可以自定义方法,进行加减乘除等各种操作
1.在表中查找,如果找到,返回该元素,找不到则继续
2.判断该表是否有元表,如果没有元表,返回 nil,有元表则继续。
3.判断元表有没有 __index 方法,如果 __index 方法为 nil,则返回 nil;如果 __index 方法是一个表,则重复 1、2、3;如果 __index 方法是一个函数,则返回该函数的返回值。
协同程序-coroutine
与线程有点类似: 拥有独立的堆栈、局部变量、指针,与其他协同程序共享全局变量和大部分逻辑
与线程区别: 一个具有多个线程的程序可以同时运行,而协同程序需要彼此协助运行;在任一指定时刻,只能有一个协同程序运行,并且只能在明确被挂起的时候才会被挂起;
协同程序类似多线程;在等待同一个线程锁的几个线程有点类似协同
(https://www.runoob.com/lua/lua-coroutine.html)
lua-文件 I/O
分为两种模式
简单模式:拥有一个当前的输入文件或输出文件,并且能够提供针对这些文件的相关操作
f = io.open(file, "r"); io.input(f); print(io.read()); io.close(f);
完全模式:使用文件句柄方式,将所有操作定义为文件句柄方法
f = io.open(file, "r"); file:seek("end", -25); file:close();
简单模式处理一些简单的文件操作较为合适,进行一些高级文件操作,需要使用完全模式,比如寻找文件当前位置,同时读取多个文件等
lua-错误处理---类似于java的try catch
语法错误、运行错误
错误处理:
assert----assert(type(a) == "number", "a 不是一个数字")
error----error (message [, level])
pcall-保护模式: 使用该函数包装需要执行的代码
pcall(function(i) print(i) end, 33)
33
true
pcall(function(i) print(i) error(‘error..‘) end, 33)
33
false stdin:1: error..
xpall-有一个错误处理函数,发生错误时调用错误处理函数
function myfunction ()
n = n/nil
end
function myerrorhandler( err )
print( "ERROR:", err )
end
status = xpcall( myfunction, myerrorhandler )
print( status)
lua-垃圾回收
lua运行一个垃圾收集器来收集所有死对象,来完成自动内存管理的工作
实现了一个增量标记-扫描收集器, 依赖两个数字:
-垃圾收集器间隙率:在开启新循环前等待多久,值为百分比。该值越大积极性越低,值<=100,收集器开启新循环前不会等待,设置为200,收集器等到内存使用量为达到之前两倍是开始循环
-垃圾收集器步进倍率:控制收集器运作速度,置为百分比。增大该值会让收集器更积极,如果该值<100,收集器工作太慢,永远干不完一个循环;默认值200, 以内存分片的2倍速率工作
lua提供collectiongarbage用来控制自动内存管理
lua-访问数据库
lua数据库的操作库LuaSQL, 是开源的
lua-面向对象
封装、继承、多态、抽象
对象有成员函数,表也有
Account = {balance = 0}
function Account.withdraw (v)
Account.balance = Account.balance - v
end
lua最新版本
5-4
我们在TString中没有看到lua将字符串的内容存在任何地方啊,其实lua是将内容同一存在了另一个地方,global_state中的strt里面:。接下来让我们来看看lua是怎样生成一个字符串的吧: