lua学习网站

lua函数

一    几个函数的特点

①    lua称之为解释型语言原因

重点:'不在于'源码是否'被编译',而在于是否'有能力'执行'动态生成'的代码 -->lua确实'存在编译阶段'

实质:lua'确实'在运行源代码'之前',将源代码'预编译'成一种'中间'形式   -->类比'Python的.pyc'

②    loadfile

lua运行时编译顺序 lua源码 编译原理_lua运行时编译顺序

loadfile故名思议:它只会'加载load'lua文件,'编译'代码,'不会运行(not running)'文件里的代码

loadfile函数:从文件中加载Lua代码块,但是它'不会'运行代码,仅仅'编译'该代码块,然后将'编译后的代码段'作为一个'函数'返回

注意: 函数loadfile只'返回错误[nil以及错误信息]',但'不抛出异常'

lua运行时编译顺序 lua源码 编译原理_预编译_02

lua运行时编译顺序 lua源码 编译原理_lua运行时编译顺序_03

  

1)自定义env

效果: 返回一个'独立'环境的函数

备注: 如果不指定'env',如同把'config.lua'整个代码'嵌入'到该位置

lua运行时编译顺序 lua源码 编译原理_lua_04

lua运行时编译顺序 lua源码 编译原理_预编译_05

lua运行时编译顺序 lua源码 编译原理_加载_06

③    dofile

lua运行时编译顺序 lua源码 编译原理_预编译_07

功能:'载入文'件并'执行'代码块,对于相同的文件'每次都会'执行

dofile是对loadfile的一次'包装'

++++++++++++++"伪代码理解"++++++++++++++

function dofile(filename)
	local func = assert(loadfile(filename))
	return func()
end

1)使用绝对路径

lua运行时编译顺序 lua源码 编译原理_lua运行时编译顺序_08

 

lua运行时编译顺序 lua源码 编译原理_lua_09

④    dofile和loadfile的区别 

共同点: 都要求'相对当前目录的文件'或"绝对路径"

dofile:读入代码文件并编译执行;每调用dofile一次,都会重新编译执行一次.

loadfile:编译代码,将'整个文件'当成一个'函数'返回,但是'不执行'代码.

 

lua运行时编译顺序 lua源码 编译原理_lua_10

1)机制

lua运行时编译顺序 lua源码 编译原理_lua运行时编译顺序_11

lua运行时编译顺序 lua源码 编译原理_lua_12

   

2)错误处理 

lua运行时编译顺序 lua源码 编译原理_lua运行时编译顺序_13

lua运行时编译顺序 lua源码 编译原理_预编译_14

3)重用性

lua运行时编译顺序 lua源码 编译原理_lua运行时编译顺序_15

 

lua运行时编译顺序 lua源码 编译原理_加载_16

④    load

1.  load从'字符串'或'函数'中'加载' --> "非文件"

备注:参数'chunkname'通常被用来作为'错误信息'和'调试信息'使用

典型场景:执行'外部'代码,即来自'程序本身之外'的代码段

lua运行时编译顺序 lua源码 编译原理_加载_17

1)字符串

备注:load'返回值'也可以'多次调用'

f = load("i = i +1;for j in pairs(_ENV) do print(j) end")  --> 通过";"将多行代码连接到一起

lua运行时编译顺序 lua源码 编译原理_预编译_18

  

lua运行时编译顺序 lua源码 编译原理_lua_19

2)函数

备注:读取'函数'作为函数load的'第1个'参数

lua运行时编译顺序 lua源码 编译原理_lua运行时编译顺序_20

+++++++++++++++++"等价形式"+++++++++++++++++

lua运行时编译顺序 lua源码 编译原理_lua_21

3)自定义env

lua5.3: 涉及'load'的第'四个'参数  --> 'load'和'loadfile'效果一样,这里以'loadfile'为例

案例: '自定义'env

机制: load加载'lua'配置文件后,该文件中'所有的定义'都会进入'自定义(new)'的环境,而'不是'继承原有的'_ENV'

效果: 返回一个'独立'环境的函数

 云大的_ENV理解 

lua运行时编译顺序 lua源码 编译原理_lua运行时编译顺序_22

lua运行时编译顺序 lua源码 编译原理_lua_23

4)等价形式

lua运行时编译顺序 lua源码 编译原理_加载_24

函数load在'编译'时不涉及'词法定界',二者'不等价'

lua运行时编译顺序 lua源码 编译原理_lua_25

lua运行时编译顺序 lua源码 编译原理_加载_26

loadstring

lua运行时编译顺序 lua源码 编译原理_lua_27

lua运行时编译顺序 lua源码 编译原理_预编译_28

  

Lua中require,dofile,loadfile,dostring,loadstring,loadlib,load之间的区别 

lua加载函数require和dofile

二    预编译的代码

lua语言会在'运行源代码之前'先对其进行'预编译'

luac命令

lua运行时编译顺序 lua源码 编译原理_预编译_29

++++++++++++++"mode模式"++++++++++++++

1.  字符串"t"允许加载'文本[源码]'类型的代码段    -->txt

2.  字符串"b"只允许加载'二进制[预编译]'类型的代码 -->binary

3.  字符串"bt"允许同时加载上述两种类型的代码段    -->'默认'

②    luac案例

字节码 --> 'bytecode'

lua运行时编译顺序 lua源码 编译原理_加载_30

lua运行时编译顺序 lua源码 编译原理_lua_31

③    lua  opcode 源码分析

lua运行时编译顺序 lua源码 编译原理_预编译_32

④    源码和预编译代码区别

体积: 一般而言,'预编译形式'的代码比'源码'体积小  --> '非绝对'

效率: 预编译代码'加载速度'更快

安全: 两种都可能被'篡改'

lua运行时编译顺序 lua源码 编译原理_预编译_33

⑤    加载预编译代码的函数

1.  几乎在lua语言中所有能够'使用源码'的地方都可以使用'预编译'代码

2.  函数'loadfile'和'load'都可以接受'预编译'代码

⑥    反编译工具

反编译主要用的工具有'unluac'和'luadec'

unluac

unluac使用方法

luadec

lua运行时编译顺序 lua源码 编译原理_预编译_34

 luagit-decomp

lua运行时编译顺序 lua源码 编译原理_加载_35

问题:把lua编译luac之后,还要进行'加密'吗?

答案:加密是可以,关键是你用的'解释器'能否读懂,所以"加密"需要'定制'的运行环境!

异常处理

(1)assert

①    语法

场景:断言(assert),一般'Debug 断点调试'

lua中的assert是一个断言,它会'中断当前'流程,'不再向下'执行

+++++++++++++'工作机制'+++++++++++++

1) 检查'参数1'是否为真  --> 'nil或false'为假

   --1.  '参数1为真'则返回'第一个参数'值

   --2.  '参数1为假'则'引发一个错误'

   备注:错误信息可以是'第二个'可选参数,也可以是'系统预设置'的

lua运行时编译顺序 lua源码 编译原理_加载_36

②    不使用assert

lua运行时编译顺序 lua源码 编译原理_预编译_37

lua运行时编译顺序 lua源码 编译原理_lua运行时编译顺序_38

  

③    使用assert但无第二个参数

lua运行时编译顺序 lua源码 编译原理_lua运行时编译顺序_39

lua运行时编译顺序 lua源码 编译原理_加载_40

  

④    使用assert但有第二个参数

lua运行时编译顺序 lua源码 编译原理_lua运行时编译顺序_41

lua运行时编译顺序 lua源码 编译原理_预编译_42

④    assert细节

assert只是一个'普通'函数,lua语言总在'调用assert函数前'先对'参数'进行求值

1)参数先执行 

lua运行时编译顺序 lua源码 编译原理_加载_43

lua运行时编译顺序 lua源码 编译原理_lua_44

2)断言正确 

lua运行时编译顺序 lua源码 编译原理_lua_45

 

lua运行时编译顺序 lua源码 编译原理_加载_46

(2)处理机制

函数发现'意外'的情况时,在进行'异常处理[exception handling]时'可以采用的两种'基本'形式

    1)返回'错误代码'  -->通常是'nil'或'false'

    2)通过'调用函数error'引发一个错误

异常:'非法地址访问'、遇到'未定义符号'、或者'断言失败'等

++++++++++++++'错误类型'++++++++++++++

1.  语法错误

2.  运行错误

(3)error

①    语法

功能:error函数是让'程序停止',进行'错误'处理  --> "抛出一个错误"

lua运行时编译顺序 lua源码 编译原理_lua_47

lua运行时编译顺序 lua源码 编译原理_lua运行时编译顺序_48

②    实践

1.  当我们在调用一个函数之'前',可以'先判断'即将传递的参数是否正常

2.  如果'不正常',我们就可以选择'直接抛出error',方便写代码的过程中'发现'问题

lua运行时编译顺序 lua源码 编译原理_预编译_49

 

lua运行时编译顺序 lua源码 编译原理_预编译_50

在C语言代码中处理Lua脚本运行产生的异常

(4)pcall

1)语法

作用:'捕获'及'处理'错误

lua运行时编译顺序 lua源码 编译原理_lua_51

解读

lua运行时编译顺序 lua源码 编译原理_预编译_52

3)实践

①    没有发生错误

返回:'true'和'函数返回值'

lua运行时编译顺序 lua源码 编译原理_lua运行时编译顺序_53

lua运行时编译顺序 lua源码 编译原理_预编译_54

②    发生错误

1.  '匿名'函数形式

2.  '约定俗成' --> ok、msg

3.  发生错误:返回'false'和'error object'

lua运行时编译顺序 lua源码 编译原理_lua_55

1.  函数'pcall'来'补获'异常

2.  错误信息用来'标识'错误的类型

lua运行时编译顺序 lua源码 编译原理_lua运行时编译顺序_56

③   经典的设计框架

lua运行时编译顺序 lua源码 编译原理_lua运行时编译顺序_57

(5)xpcall

lua运行时编译顺序 lua源码 编译原理_lua运行时编译顺序_58

lua运行时编译顺序 lua源码 编译原理_加载_59

lua日志