1.关于table
Lua官方文档对table库的描述:
This library provides generic functions for table manipulation. It provides all its functions inside the table
table
.
使用起来很简单:
local sortn = table.concat( {1,2,3,4}, "&")
print(sortn) -- 1&2&3&4
其实,table本身就是一个‘table’,用type可以查看:
print(type(table)) -- table
可以查看当前版本lua中table有哪些方法:
for k,v in pairs(table) do
print(k,v)
end
我当前使用的是Lua 5.1的版本,输出:
2.关于string
Lua官方对string库的描述:
The string library provides all its functions inside the table
string
. It also sets a metatable for strings where the__index
field points to thestring
table. Therefore, you can use the string functions in object-oriented style. For instance,string.byte(s, i)
can be written ass:byte(i)
.
也就是说,Lua提供了一个表string来操作字符串,而且你可以用面向对象的方式(用冒号:)来使用其提供的方法。
使用起来很简单:
local s = 'abc'
print(string.rep(s,3)) --abcabcabc
print(s.rep(s,3)) --abcabcabc
print(s:rep(3)) --abcabcabc
第一种使用方法很好理解 ,是官方推荐的用法,这里探索一下第二和第三种使用方法。
s:rep(3)
这种面向对象的方法,其实也就是在函数内部增加了一个隐藏参数self,而这个参数指向的是调用者本身,也就是代码中的s。那么,这种面向对象的方式也就可以写成:
s.rep(s,3)
这种调用方式等于显式的把self赋值为s,也就很好理解了这种写法。而值得注意的一点是:为什么字符串s可以当作表来使用呢?我们再仔细研究这句话:
It also sets a metatable for strings where the
__index
field points to thestring
table
关键就是这句话,原来每个字符串都有一个元表,这个元表的元方法__index指向了标准库提供的string这个表。我们来验证一下:
print(string) --table: 000382a8
print(getmetatable(string)) --nil
local stb = getmetatable(s)
print(stb) --table: 000380c8
print(stb.__index) --table: 000382a8
从输出可以看出,string就是一个表,它本身是没有元表的; 字符串s存在一个元表,这个元表的元方法__index指向了一个表,从地址可以看出其实就是string表。这就解释了上面的问题:“为什么字符串s可以当作表来使用?”,其实调用的还是string这个表中的方法。
3.容易迷惑的点
从官方描述可以看出,表的标准库提供的方法都在table表中,这个表是没有元表的:
print(getmetatable(table)) --nil
也就是说,我们自己创建的表是不能像字符串那样调用标准库里提供的方法:
local xt = {1,2}
xt.sort(xt) -- 报错:attempt to call a nil value (field 'sort')
如上可见,通过表构造器生成的表xt并不能直接调用标准库table里的方法,说明xt没有类似字符串那样的一个元表:
local xt = {1,2,3}
print(getmetatable(xt)) --nil
可见,普通的表默认是没有元表的。
以上,就是Lua中string库和table库的区别。简单总结,欢迎指正。