一 几个函数的特点
① lua称之为解释型语言原因
重点:'不在于'源码是否'被编译',而在于是否'有能力'执行'动态生成'的代码 -->lua确实'存在编译阶段'
实质:lua'确实'在运行源代码'之前',将源代码'预编译'成一种'中间'形式 -->类比'Python的.pyc'
② loadfile
loadfile故名思议:它只会'加载load'lua文件,'编译'代码,'不会运行(not running)'文件里的代码
loadfile函数:从文件中加载Lua代码块,但是它'不会'运行代码,仅仅'编译'该代码块,然后将'编译后的代码段'作为一个'函数'返回
注意: 函数loadfile只'返回错误[nil以及错误信息]',但'不抛出异常'
1)自定义env
效果: 返回一个'独立'环境的函数
备注: 如果不指定'env',如同把'config.lua'整个代码'嵌入'到该位置
③ dofile
功能:'载入文'件并'执行'代码块,对于相同的文件'每次都会'执行
dofile是对loadfile的一次'包装'
++++++++++++++"伪代码理解"++++++++++++++
function dofile(filename)
local func = assert(loadfile(filename))
return func()
end
1)使用绝对路径
④ dofile和loadfile的区别
共同点: 都要求'相对当前目录的文件'或"绝对路径"
dofile:读入代码文件并编译执行;每调用dofile一次,都会重新编译执行一次.
loadfile:编译代码,将'整个文件'当成一个'函数'返回,但是'不执行'代码.
1)机制
2)错误处理
3)重用性
④ load
1. load从'字符串'或'函数'中'加载' --> "非文件"
备注:参数'chunkname'通常被用来作为'错误信息'和'调试信息'使用
典型场景:执行'外部'代码,即来自'程序本身之外'的代码段
1)字符串
备注:load'返回值'也可以'多次调用'
f = load("i = i +1;for j in pairs(_ENV) do print(j) end") --> 通过";"将多行代码连接到一起
2)函数
备注:读取'函数'作为函数load的'第1个'参数
+++++++++++++++++"等价形式"+++++++++++++++++
3)自定义env
lua5.3: 涉及'load'的第'四个'参数 --> 'load'和'loadfile'效果一样,这里以'loadfile'为例
案例: '自定义'env
机制: load加载'lua'配置文件后,该文件中'所有的定义'都会进入'自定义(new)'的环境,而'不是'继承原有的'_ENV'
效果: 返回一个'独立'环境的函数
4)等价形式
函数load在'编译'时不涉及'词法定界',二者'不等价'
Lua中require,dofile,loadfile,dostring,loadstring,loadlib,load之间的区别
二 预编译的代码
lua语言会在'运行源代码之前'先对其进行'预编译'
luac命令
++++++++++++++"mode模式"++++++++++++++
1. 字符串"t"允许加载'文本[源码]'类型的代码段 -->txt
2. 字符串"b"只允许加载'二进制[预编译]'类型的代码 -->binary
3. 字符串"bt"允许同时加载上述两种类型的代码段 -->'默认'
② luac案例
字节码 --> 'bytecode'
④ 源码和预编译代码区别
体积: 一般而言,'预编译形式'的代码比'源码'体积小 --> '非绝对'
效率: 预编译代码'加载速度'更快
安全: 两种都可能被'篡改'
⑤ 加载预编译代码的函数
1. 几乎在lua语言中所有能够'使用源码'的地方都可以使用'预编译'代码
2. 函数'loadfile'和'load'都可以接受'预编译'代码
⑥ 反编译工具
反编译主要用的工具有'unluac'和'luadec'
问题:把lua编译luac之后,还要进行'加密'吗?
答案:加密是可以,关键是你用的'解释器'能否读懂,所以"加密"需要'定制'的运行环境!
异常处理
(1)assert
① 语法
场景:断言(assert),一般'Debug 断点调试'
lua中的assert是一个断言,它会'中断当前'流程,'不再向下'执行
+++++++++++++'工作机制'+++++++++++++
1) 检查'参数1'是否为真 --> 'nil或false'为假
--1. '参数1为真'则返回'第一个参数'值
--2. '参数1为假'则'引发一个错误'
备注:错误信息可以是'第二个'可选参数,也可以是'系统预设置'的
② 不使用assert
③ 使用assert但无第二个参数
④ 使用assert但有第二个参数
④ assert细节
assert只是一个'普通'函数,lua语言总在'调用assert函数前'先对'参数'进行求值
1)参数先执行
2)断言正确
(2)处理机制
函数发现'意外'的情况时,在进行'异常处理[exception handling]时'可以采用的两种'基本'形式
1)返回'错误代码' -->通常是'nil'或'false'
2)通过'调用函数error'引发一个错误
异常:'非法地址访问'、遇到'未定义符号'、或者'断言失败'等
++++++++++++++'错误类型'++++++++++++++
1. 语法错误
2. 运行错误
(3)error
① 语法
功能:error函数是让'程序停止',进行'错误'处理 --> "抛出一个错误"
② 实践
1. 当我们在调用一个函数之'前',可以'先判断'即将传递的参数是否正常
2. 如果'不正常',我们就可以选择'直接抛出error',方便写代码的过程中'发现'问题
在C语言代码中处理Lua脚本运行产生的异常
(4)pcall
1)语法
作用:'捕获'及'处理'错误
解读
3)实践
① 没有发生错误
返回:'true'和'函数返回值'
② 发生错误
1. '匿名'函数形式
2. '约定俗成' --> ok、msg
3. 发生错误:返回'false'和'error object'
1. 函数'pcall'来'补获'异常
2. 错误信息用来'标识'错误的类型
③ 经典的设计框架
(5)xpcall
lua日志