gpt4 book ai didi

具有 nil 值的 Lua 长度运算符 (#)

转载 作者:行者123 更新时间:2023-12-05 00:47:24 24 4
gpt4 key购买 nike

看完this topic经过一番试验,我试图了解当表包含 nil 值时 Lua 长度运算符的工作原理。

在我开始调查之前,我认为长度只是连续的非零元素的数量,从索引 1 开始:

print(#{nil})         -- 0
print(#{"o"}) -- 1
print(#{"o",nil}) -- 1
print(#{"o","o"}) -- 2
print(#{"o","o",nil}) -- 2

这看起来很简单,对吧?

但是当我不小心在一个以 nil 结尾的表格后添加了一个元素时,我就开始头疼了:

print(#{"o",nil,"o"})

我的猜测是它可能应该打印 1,因为当找到第一个 nil 时它会停止计数。或者,如果长度运算符足够贪婪以在第一个 nil 之后查找非 nil 元素,它可能应该打印 2。但是上面的代码打印出 3。

所以我运行了 several other tests看看会发生什么:

-- nil before the end
print(#{nil,"o"}) -- 2
print(#{nil,"o","o"}) -- 3
print(#{"o",nil,"o"}) -- 3

-- several nil elements
print(#{"o",nil,nil}) -- 1
print(#{nil,"o",nil}) -- 0
print(#{nil,nil,"o"}) -- 3

我应该提一下,repl.it 目前使用的是相当旧的 Lua 5.1.5,但是如果您使用 Lua demo 进行测试,目前使用 Lua 5.3.5,您将获得相同的结果。

通过查看这些结果并查看 at this answer ,我假设:

  • 如果最后一个元素不是 nil,则长度运算符返回表的完整大小,包括 nil 条目(如果有)
  • 如果最后一个元素为 nil,则计算连续非 nil 的个数,并在第一个 nil 处停止计数

这些假设正确吗?

当表包含一个或多个 nil 值时,我们能否预测 100% 明确定义的行为?

Lua 文档指出 the length of a table is only defined if the table is a sequence .这是否意味着长度运算符对非序列有未定义的行为?

除了长度操作符之外,nil 值会不会对表造成任何麻烦?

最佳答案

我们可以预测一些行为,但它不是标准化的,因此你不应该依赖它。在这个主要版本的 Lua 中行为很可能会发生变化。

如果您需要用 nil 值填充表格,我建议包装表格并用唯一的占位符值替换孔(例如。NIL={}; if v==nil then t[k]= NIL 结束,这是相当便宜的测试和安全。)。

也就是说……

由于根据表的定义方式,# 的结果甚至会有所不同,因此您必须区分静态定义(常量)表和动态定义(静音)表。

静态表定义:

#{nil,nil,nil,nil,nil,  1} -- 6
#{3, 2, nil, 1} -- 4

#{nil,nil,nil, 1, 1,nil} -- 0
#{nil,nil, 1, 1, 1,nil} -- 5
#{nil, 1, 1, 1, 1,nil} -- 5
#{nil,nil,nil,nil, 1,nil} -- 0
#{nil,nil, 1,nil, 1,nil,nil} -- 5
#{nil,nil,nil, 1,nil,nil, 1,nil} -- 4

使用这种定义,只要最后一个值不是nil,就会得到一个等于最后一个值位置的长度。如果最后一个值为 nil,Lua 从尾部开始(非线性)搜索,直到找到第一个非 nil 值。

动态数据定义

local x={}; x[5]=1;print(#x) -- 0
local x={}; x[1]=1;x[2]=1;x[3]=1;x[5]=1;print(#x) -- 3
local x={}; x[1]=1;x[2]=1;x[4]=1;x[5]=1;print(#x) -- 5

#{[5]=1} -- 0
local x={nil,nil,nil,1};x[5]=1;print(#x) -- 0

一旦表被更改一次,运算符(operator)就会以另一种方式工作(包括 static 定义与 [])。如果第一个元素是 nil,# 总是返回 0,但如果不是,它会启动我没有进一步调查的搜索(我想你可以查看来源,虽然我不要认为这是一个标准的二分查找),直到它找到一个前面有一个非零值的 nil 值。

如前所述,依赖这种行为并不是一个好主意,并且会引发很多问题。虽然如果你想制作一个令人讨厌的不可维护的程序来惹恼同事,那是一种肯定的方法。

关于具有 nil 值的 Lua 长度运算符 (#),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57377515/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com