LUA 进阶
环境
1 | lua -e "for k,v in pairs(_G) do print(k,v) end" | sort |
lua全局环境变量保存在_G的table中,内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39assert function: 0
collectgarbage function: 0x99f5bd0
coroutine table: 0x99f6718
debug table: 0x99f97d0
dofile function: 0x99f5c88
error function: 0x99f5cc0
gcinfo function: 0x99f5c10
getfenv function: 0x99f5c48
getmetatable function: 0x99f5de0
_G table: 0x99f5450
io table: 0x99f79e8
ipairs function: 0x99f59a0
loadfile function: 0x99f5e20
load function: 0x99f5cf8
loadstring function: 0x99f5d30
math table: 0x99f8dd0
module function: 0x99f6ce0
newproxy function: 0x99f66b0
next function: 0x99f5d68
os table: 0x99f81f0
package table: 0x99f6a50
pairs function: 0x99f5a00
pcall function: 0x99f5da0
print function: 0x99f6020
rawequal function: 0x99f6058
rawget function: 0x99f6090
rawset function: 0x99f60c8
require function: 0x99f6f88
select function: 0x99f5478
setfenv function: 0x99f5e58
setmetatable function: 0x99f5e90
string table: 0x99f65b8
table table: 0x99f6828
tonumber function: 0x99f5ed0
tostring function: 0x99f5f08
type function: 0x99f5f40
unpack function: 0x99f5f78
_VERSION Lua 5.1
xpcall function: 0x99f5fb0setfenv(set function environment)改变一个函数的环境,该环境参数是一个函数层级和一个table,函数层级1表示当前函数,2表示调用当前函数的函数,以此类推
1
setfenv(1, {g = _G})
由于函数继承创建其函数的环境,所以一个程序块改变了自己的环境,后续由它创建的函数都共享新环境
模块和包
require
- require调用返回一个模块函数组成的table,并且定义一个包含改table的全局变量
require采用一串路径模式,每个模式都包含一个可选的?, require用模块名替换?,来查找这个文件,如果不存在,将寻找下一项。假设路径为
1
2
3
4
5?;?.lua;/usr/local/lib/?.lua?;
执行require "sql"将尝试打开如下文件
sql
sql.lua
/usr/loca/lib/sql.luarequire 搜索路径在_G.package.path中定义,如果无法找到将寻找c库,路径在_G.package.cpath中定义
- 如果模块没有返回值,require返回package.loaded[modename]的值
module函数
1 | module(..., package.seeall) 等价于如下代码: |
1 | local modname = ... |
子模块与包
lua支持层级模块,中间使用.分割。比如mod.sub就是sub的子模块,require搜索路径时将.转换为系统路径(/或)
面向对象
lua使用冒号(:)隐藏self参数,函数内仍可以通过self参数访问成员
1
table.sub(table, 10) => table:sub(10)
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#!/usr/bin/env lua
Account = { balance = 0, withdraw = function(v)
self.balance = self.balance - v
end }
function Account:deposit(v)
self.balance = self.balance + v
end
function Account:new(o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
a = Account:new()
print (a.balance)