转载自:https://github.com/lujun9972/lujun9972.github.com/blob/source/%E7%BC%96%E7%A8%8B%E4%B9%8B%E6%97%85/lua %E4 %B8%AD%E7%A5%9E%E5%A5%87%E7%9A%84table.org
作者:lujun9972
我最近在尝试建立一个漂亮的WM 时简要了解了lua。 在我的学习过程中,我对Lua对表((tables))的应用彻底着迷了。
表实际上在Lua 中无处不在。首先,表可以用作字典和数组,也可以用来设置闭包环境和模块,还可以用来模拟对象和类。
字典
表最基本的功能就是将其用作字典。 键可以是除nil 之外的任何类型的值。
t={}
t[{}]='table' -- 键可以是表
t[1]='int' -- key 可以是整数
t[1.1]='double' -- key 可以是十进制数
t[function () end]='function' -- key 可以是一个函数
t[true]='Boolean' -- 键可以有布尔值
t['abc']='String' -- 键可以是字符串
t[io.stdout]='userdata' -- key 可以是用户数据
t[coroutine.create(function () end)]='thread' -- key 可以是一个线程
当使用表作为字典时,可以使用pairs函数来迭代表。
对于一对(t) k,v,
打印(k,'-',v)
结尾
执行结果如下。
1-整数
1.1倍
thread:0x220bb08 - 线程
table:0x220b670 - 表
abc - 字符串
文件(0x7f34a81ef5c0) - 用户数据
function:0x220b340 - 功能
true - 布尔值
结果还表明,使用成对遍历时顺序是随机的。事实上,如果多次运行同一条语句,将会得到不同的结果。
表中最常见的两种键类型是整数和字符串。 如果键是字符串,则可以将表用作结构体。同时,写成t['field']的形式可以简写为t.field。
数组
如果键是整数,表可以用作数组。并且这个数组从索引1开始,没有固定长度,并且可以根据需要自动增长。
一个={}
for i=0,5 do -- 请注意,i 是故意写为从0 开始的。
a[i]=0
结尾
当使用表作为数组时,可以使用长度运算符#来获取数组的长度。
打印(#a)
结果如下。
五
可以看到Lua认为数组a只有5个元素。它的五个元素是什么?您可以使用ipairs 来迭代数组。
对于ipairs(a) 中的i,v 执行
打印(一,五)
结尾
结果如下。
十
2 0
3 0
4 0
5 0
结果表明,a 的0 索引不被视为数组中的元素。这也验证了Lua中的数组是从1开始索引的。
另外,如果将表用作数组,则需要注意索引不一致。在这种情况下# 长度计算会很奇怪。
一个={}
如果i=1,5 则执行
a[i]=0
结尾
a[8]=0 -- 索引不一致,但长度基于最大索引。
打印(#a)
a[100]=0 -- 索引不一致且长度不基于最大索引。
打印(#a)
结果如下。
8
8
使用ipairs遍历数组时,只会从1开始遍历到下标处。
对于ipairs(a) 中的i,v 执行
打印(一,五)
结尾
结果如下。
十
2 0
3 0
4 0
5 0
环境(命名空间)
lua 将所有全局/局部变量存储在常规表中。该表通常称为函数的全局或环境(闭包)。
为了方便起见,Lua在创建第一个全局环境时使用全局变量_G来引用全局环境。因此,-G[varname]允许您访问全局变量的值,而无需手动设置环境。
关于k,v 对(_G)
打印(k,'-',v)
结尾
原始平等功能:0x41c2a0
要求功能:0x1ea4e70
_版本- Lua 5.3
调试表:0x1ea8ad0
字符串表:0x1ea74b0
xpcall-function:0x41c720
选择功能:0x41bea0
封装表:0x1ea4820
断言函数:0x41cc50
pcall-function:0x41cd10
下一个函数:0x41c450
tostring-function:0x41be70
_G - 表:0x1ea2b80
协程表:0x1ea4ee0
解包功能:0x424fa0
加载字符串函数:0x41ca00
设置元表函数:0x41c7e0
rawlen-function:0x41c250
位32-table:0x1ea8fc0
utf8-table:0x1ea8650
数学表:0x1ea7770
收集垃圾函数:0x41c650
原始集函数:0x41c1b0
操作系统表:0x1ea6840
配对功能:0x41c950
arg-table:0x1ea9450
表:0x1ea5130
tonumber-function:0x41bf40
io-table:0x1ea5430
加载文件函数:0x41cb10
错误函数:0x41c5c0
加载函数:0x41ca00
打印函数:0x41c2e0
dofile-function:0x41cbd0
rawget-function:0x41c200
类型-功能:0x41be10
获取元表函数:0x41cb80
模块功能:0x1ea4e00
ipairs-function:0x41c970
从Lua 5.2开始,您可以通过更改_ENV的值来设置函数的环境(Lua 5.1中的setfenv从5.2开始已弃用),从而允许该函数的执行语句在新环境中查找全局变量。价值。
a=1 -- 全局变量a=1
local env={a=10,print=_G.print} -- 新环境中a=10,保证全局打印功能可以访问。
函数f1()
local_ENV=环境
print('在f1:a=',a)
a=a*10 -- 改变的是新环境中a的值。
结尾
f1()
print('globally:a=',a)
print('env.a=',env.a)
f1:a=10
全局:a=1
环境a=100
此外,新创建的闭包会继承创建它的函数的环境。
模块
lua 中的模块还返回表供模块用户使用。 该表包含模块导出的所有内容,例如函数和常量。
定义模块的通用模板是:
模块(模块名称,包.seeall)
模块(模块名称)的功能如下。
本地modname=模块名称
local M={} -- M是一个表,存储模块的所有函数和常量
_G[模组名称]=M
package.loaded[modname]=M
setmetatable(M,{__index=_G}) -- package.seeall可以使全局环境_G对当前环境可见。
local _ENV=M -- 设置当前执行环境为M。这样就无需在所有后续代码中限定模块名称,并且定义的所有函数都会自动成为M 的成员。
函数和常量定义
return M -- 模块函数返回模块表,无需手动返回模块表。
对象
表可以用作Lua 中的对象,原因如下:
函数是Lua中的一种值类型,可以直接访问表中的函数值。 这允许表拥有自己的行为和状态:Account={balance=0}
函数Account.withdraw(v)
账户余额=账户余额- v
结尾
Lua支持闭包,可以用来模拟对象的私有成员变量: function new_account(b)
本地余额=b
返回{提款=函数(v)余额=余额-v退出,
get_balance=function() 返回余额结束
}
结尾
a1=新账户(1000)
a1. 提款(10)
打印(a1.get_balance())
990
然而,上面定义对象的第一种方法是有缺陷的。也就是说,该方法绑定到名称Account。 也就是说,该对象必须命名为Account,否则您将收到错误。
a=帐户
帐户=无
a.withdraw(10) -- 报错,因为Account.balance不存在。
为了解决这个问题,给withdraw方法一个额外的参数,指向对象本身。
账户={余额=100}
函数Account.withdraw(self,v)
自平衡=自平衡-v
结尾
a=帐户
帐户=无
a.withdraw(a,10)——没问题。当前self 指向a,因此会搜索a.balance。
打印(a.余额)
90
然而,由于第一个参数self 通常指的是调用该方法的对象本身,Lua 提供了语法糖object:method(.) 来隐藏self 参数的定义和转发。这里的冒号有两个功能。定义函数时在函数的第一个参数位置添加一个额外的隐藏参数sef,调用时在第一个参数位置传递一个额外的隐藏参数self。 也就是说,函数object:method(v) end 相当于函数object.method(self,v) end,object:method(v) 相当于object.method(object,v)。
类
关于类和继承,使用元表和元方法。事实上,在Lua中对象和类之间并没有严格的区别。
当一个对象在另一个表的__index 元方法中引用时,该表可以引用该对象上定义的方法,因此我们知道该对象是该表的一个类。
类定义的通用模板是:
函数类名:new(o)
o=o 或{}
setmetatable(o,{__index=self})
回去
结尾
或者:
函数类名:new(o)
o=o 或{}
设置元表(o,self)
self.__索引=self
回去
结尾
相反,第二个表示法允许您省略另一个表。
我认为需要解释的另一件事是Lua的元方法是在元表中定义的,而不是在对象本身上定义的。这与其他面向对象语言不同。
点击“了解更多”可访问文内链接
版权声明:本文转载于今日头条,版权归作者所有。如有侵权,请联系本站编辑删除。