表达式用于表示值。Lua 的表达式中可以包含数字常量、字面字符串、变量、一元和二元操作符及函数调用。另外有别于传统的是,表达式中还可以包括函数定义和 table 构造式。

1、实现了关联数组(具有特殊索引方式的数组)

不仅可以通过整数来索引它,还可以使用字符串其他类型的值(除了nil)来索引它

2、没有固定大小,可以动态地添加任意数量的元素到一个 table 中

3、通过 table 来表示模块、包、对象

如,输入 io.read() 时,对于 lua,表示使用字符串 "read" 作为 key 来索引 "table.io"

4、在 lua 中,table 是"对象",可以将一个 table 想象成一种动态分配的对象。程序仅持有一个对他们的引用(或指针)。lua 不会暗中产生 table 的副本或者创建新的table

5、不需要声明

6、table 的创建是通过"构造表达式"完成的,最简单的"构造表达式"——{}

a = {}
a[k] = 10
print(a[k])  -- 10

7、table 永远是"匿名的",一个持有 table 的变量与 table 自身之间没有固定的关联性

a = {}
a['x'] = 10
b = a  -- b 和 a 引用了同一个 table
print(b['x'])  -- 10
b['x'] = 20
print(a['x'])  --20
a = nil  -- 只有 b 还在引用 table
b = nil  -- 没有对 table 的引用了

当一个程序再没有对一个 table 的引用时,lua 的垃圾收集器最终会删除该 table,并复用它的内存

8、语法糖

a.x = 10 等价于 a['x'] = 10
a = {}
x = 'y'
a[x] = 10
print(a[x])  -- 10
print(a.x)  -- nil
print(a.y)  --10

9、若表示一个传统的数组或者线性表,只需以整数作为 key 来使用 table 即可

a = {}
for i = 1,10 do
    a[i] = io.read()
    end

10、长度

① 长度操作符"#"用于返回一个数组或者线性表的最后一个索引值(计算的是数组元素,不包括 hash 键值)

a = {}
for i = 1,10 do
    a[i] = io.read()  -- 1 2 3 4 5 6 7 8 9 10
    end
for i = 1,#a do
    io.write(a[i])  -- 1 2 3 4 5 6 7 8 9 10
    end
print(a[#a])  -- 10
a[#a+1] = 11  -- 将11添加到列表末尾
print(a[#a])  -- 11
print(a[#a+1])  -- nil

另外一种方法读取文件的前 10 行

a = {}
for i =1,10 do 
    a[#a+1] = io.read()
    end

② 未初始化的元素的索引结果都是 nil,Lua 将 nil 作为界定数组结尾的标志,处理含有"空隙"的数组,使用函数 table.maxn(),它将返回一个 table 的最大正索引数

a = {}
a[1000] = 1
print(#a)  -- 0
print(table.maxn(a))  -- 1000

③ table.getn()(同 #)

local tblTest2 =
{
    1,
    a = 2,  -- 记录
    3,
}
print(table.getn(tblTest2))  -- 1
  • 这个tblTest2不是一个简单的table,它混合了列表(list)和记录(record)两种风格,表中,a = 2是record风格。其次,record风格的record是不作为外表的长度计算。可以把它想象成一个函数,跟其他面向对象语言一样,函数是不记为内部变量的。
  • 既然像函数一样,那就可以输出a的值。print(tblTest2.a)就可以了。

    t= {
      [1]=4,
      [2]=5,
      [3]=6,
      [4]=7,
      [6]=8,
    }
    print("#" ,#t , "getn",table.getn(t) ,"maxn", table.maxn(t) )  -- 6 6 6
    print(t[5])`  -- nil
    t= {
      [1]=4,
      [2]=5,
      [3]=6,
      [5]=7,
      [6]=8,
    }
    print("#" ,#t , "getn",table.getn(t) ,"maxn", table.maxn(t) )  -- 3 3 6

    这里也太神奇了叭,真的搞不懂啊,哭了!

11、和全局变量一样,当 table 的某个元素没有初始化时,它的内容就为 nil,将 nil 赋予 table 的元素来删除该元素

但是!

local tblTest4 =
{
    1,
    nil,
}
print(table.getn(tblTest4))  -- 1
local tblTest5 =
{
    1,
    nil,
    2,
}
print(table.getn(tblTest5))  -- 3
local tblTest5 =
{
1,
nil,
2,
nil
}
print(table.getn(tblTest5))  -- 1

所以!

  • 在table中不要使用nil
  • 如果非要使用nil,必须用table.setn()函数去设置这个table表的长度。新版本的lua已经不支持setn了。
  • setn函数已过时,不要在lua的table中使用nil值,如果一个元素要删除,直接remove,不要用nil去代替。

12、key = '+1'、key = ‘01’ 和 key = ‘1’ 三者不同,当对索引的实际类型不是很确定时,可以明确地使用 tonumber()显示转换

1、boolean: false 和 true

2、lua 将值 false 和 nil 视为“假”,而其他值视为“真”

3、lua 在条件测试中,将 0 和 空字符串 也都视为”真“