为什么我的 LUA 解释器无法处理字符串键值?



当使用预定义脚本和 LUA 运行时环境测试代码时,LUA 不会采用任何形式的字符串键值。但是,如果使用数值键,LUA 将按预期使用它。当我将 Tshark 与 LUA 文件一起使用来解析数据包捕获时,此规则的例外情况。这允许字符串键值语法正常工作。我可能做错了什么吗?

我尝试创建几个具有不同变体的.lua脚本文件,包括:

testArray.NewItem = "value1" testArray["NewItem"] = "value1">

NewItemValue = "NewItem" testArray[NewItemValue] = "value1">

这些都会导致 nil 值或由于尝试调用 nil 值而导致错误,具体取决于用于检查的返回样式。

> tcpstream = {}
> stream1 = tostring(14356)
> tcpstream[stream1] = "nothing"
> print(#tcpstream)
0
> print(tcpstream[1])
nil
> tcpstream[1] = "nothing"
> print(#tcpstream)
1
> print(tcpstream[1])
nothing

在 tcpstream[stream1] = "nothing" 之后的 print(#tcpstream) 输出应显示 1 而不是零。随后的打印(tcpstream[1])也应该显示"无"。

来自 http://lua-users.org/wiki/TablesTutorial

# 运算符不计算表 (!) 中的所有项目。相反,它找到最后一个整数(非小数)键。由于它的实现方式,如果表中的所有整数键都不连续,则其结果是未定义的。这就是为什么它不应该用于用作稀疏数组的表[2])。

"#"不是计算Lua表中元素数量的好方法(有时不正确)。

至于

> stream1 = tostring(14356)
> tcpstream[stream1] = "nothing"
> print(#tcpstream)
0
> print(tcpstream[1])
nil

Lua 使用键、值对,而不是显式索引。如果你执行 'arr[1] = 22',则意味着键 '1' 的值是 22,而不是第一个元素的值是 22。

长度运算符(#) 并不像您认为的那样工作,这是 Lua 初学者的常见错误。

#sometable的默认行为是返回从数字1开始的连续键数(或 5.3 的任何 nil 值之后)。字符串键永远不会使用表的默认#运算符进行计算。

在 5.3 中,如果您的序列包含多个 nil 值,则#的行为是不确定的。

Lua 5.3 参考手册:3.4.7 – 长度运算符

Lua 5.1 参考手册:2.5.5 – 长度运算符

我将包括 5.1 中的行,因为我觉得它很好地涵盖了有关运算符和表格的信息。虽然注意与 5.3 的工作方式相同,但可能更容易理解为什么你会看到你所做的行为。

2.5.5 – 长度运算符 长度运算符由一元运算符 # 表示。字符串的长度是其字节数(即,当每个字符为一个字节时,字符串长度的通常含义)。

表 t 的长度定义为任何整数索引 n,使得 t[n] 不是 nil 并且 t[n+1] 是 nil;此外,如果 t1 为 nil,n 可以为零。对于一个正则数组,从 1 到给定 n 的非 nil 值,它的长度正好是 n,即其最后一个值的索引。如果数组有"孔"(即其他非 nil 值之间的 nil 值),则 #t 可以是直接在 nil 值之前的任何索引(也就是说,它可以将任何此类 nil 值视为数组的末尾)。

以下是不同表及其#结果的一些示例:

table1 = { --number keys in array
true,
true,
true,
}
table2 = { -- number keys in hash
[1] = true,
[2] = true,
[3] = true,
}
table3 = { -- only strings as key
['1'] = true,
['2'] = true,
['3'] = true,
}
table4 = { -- No key 2 defined
[1] = true,
-- [2] = true, 
[3] = true,
}
table5 = { -- table with both string and number keys
[1] = true,
['2'] = true,
}
print(#table1) -- 3
print(#table2) -- 3
print(#table3) -- 0
print(#table4) -- v5.3(1 or 3) v5.1(1)
print(#table5) -- 1

最新更新