g = function () i = i + 1 end
这个例子中, 和想象的一样g 使用局部变量i , 然而f 使用全局变量i ; loadstring 总是在全局环境中编译他的串。
i = 100 local i = 0 f = loadstring("i = i + 1 print(i)") g = function () i = i + 1 print(i) end print(f()) print(g()) -- 输出结果: 101 1
2,require 和dofile 完成同样的功能但有两点不同:
=> require 会搜索目录加载文件
为了确定路径, Lua 首先检查全局变量LUA_PATH 是否为一个字符串, 如果是则认为这个串就是路径; 否则require 检
查环境变量LUA_PATH的值, 如果两个都失败require 使用固定的路径( 典型的"?;?.lua" )
Lua 保留一张所有已经加载的文件的列表( 使用table 保存) 。如果一个加载的文件在表中存在require 简单的返回; 表
中保留加载的文件的虚名, 而不是实文件名。所以如果你使用不同的虚文件名require 同一个文件两次,将会加载两次该文
件。比如require "foo" 和
require "foo.lua" , 路径为"?;?.lua" 将会加载foo.lua 两次。我们也可以通过全局变量_LOADED访问文件名列表。
在require运行一个chunk 以前, 它定义了一个全局变量_REQUIREDNAME 用来保存被required 的虚文件的文件名。
dofile当作Lua运行代码的chunk的一种原始的操作。dofile实际上是一个辅助的函数。真正完成功能的函数是loadfile;与dofile不同的是loadfile编译代码成中间码并且返回编译后的chunk作为一个函数,而不执行代码;另外loadfile不会抛出错误信息而是返回错误代。我们可以这样定义dofile:
3,lua的错误处理(断言)
n = assert(io.read("*number"), "invalid input")
assert 首先检查第一个参数, 若没问题, assert不做任何事情; 否则, assert 以第二个参数作为错误信息抛出。第二个参
数是可选的。注意, assert 会首先处理两个参数, 然后才调用函数。
基本的原则是: 对于程序逻辑上能够避免的异常, 以抛出错误的方式处理之, 否则返回错误代码。
4,如果在Lua 中需要处理错误, 需要使用pcall 函数封装你的代码。
local status, err = pcall(function () error({code=121}) end)
两个常用的debug 处理函数: debug.debug 和debug.traceback;
也可以用xpcall来来处理错误,并可将其封装为此下trycall函数(方便使用):
-- 打印错误信息 local function __TRACKBACK__(errmsg) local track_text = debug.traceback(tostring(errmsg), 6); print("---------------------------------------- TRACKBACK ----------------------------------------"); print(track_text, "LUA ERROR"); print("---------------------------------------- TRACKBACK ----------------------------------------"); local exception_text = "LUA EXCEPTION\n" .. track_text; return false; end --[[ 尝试调一个function 这个function可以带可变参数 如果被调用的函数有异常 返回false,退出此方法继续执行其他代码并打印出异常信息;]] function trycall(func, ...) local args = { ... }; return xpcall(function() func(unpack(args)) end, __TRACKBACK__); end --测试代码: trycall(function(param) print("message "..param) print("message "..nil) end, "test trycall")
5,lua中的对象
当一个表的metatable存在一个__index函数时,如果Lua调用一个原始表中不存在的函数,Lua将调用这个__index指定的函数。
这样可以用__index实现在多个父类中查找子类不存在的域。
local a, b = ...如果需要作为table使用,则将其放 入{} 即可for i,v in ipairs({...}) do print(v) end如果...中含有nil,则
最好通过 select函数来访问for i=1, select("#", ...) do print(select(i, ...)) end
7,解释器
8.__call元方法释义
meta = {} meta.__call = function(obj, param1, param2) print(obj, param1, param2) print(obj.test) end a = {} setmetatable(a, meta) a.test = "Oh-yeah" a(a.test, 99)
-- 输出结果:
table: 0x7fd2f9404fc0 Oh-yeah 99
Oh-yeah