在Lua中,如何正确处理包含nil的可变参数?

我正在尝试创建一个调试打印函数,它以文件句柄作为第一个参数。首先,我编写了一个像这样的函数:

function fprint (f, ...)
   for i, v in ipairs{...} do
      f:write(tostring(v))
      f:write("\t")
   end
   f:write("\n")
end

只要我不在参数中传递nil值,这个函数就可以工作。但是,如果我用nil调用它,它不会打印出nil值和其他参数。

fprint(io.stderr, 1, 2, nil, 3)
=> 仅打印12

那么,如何正确解决这个问题?

原文链接 https://stackoverflow.com/questions/7183998

点赞
stackoverflow用户596285
stackoverflow用户596285

据我所知,没有一种易于实现且独立于实现方式的方法可以知道包含nil条目的数组的长度,因为#操作可以指向后面跟着nil的任何位置,但是这是一种快速实现相关的解决方案,将打印出nil

function fprint (f, ...)
   local parm={...}
   for i=1,#parm do
      f:write(tostring(parm[i]))
      f:write("\t")
   end
   f:write("\n")
end

与其依赖于#,你可以做得更复杂(因此与实现无关),因为你知道parm表是一个数组,可以使用以下内容:

function last_index(array)
  local max = 0
  for k, _ in pairs(array) do
    max = math.max(max, k)
  end
  return max
end

function fprint (f, ...)
   local parm={...}
   for i=1,last_index(parm) do
      f:write(tostring(parm[i]))
      f:write("\t")
   end
   f:write("\n")
end

如果你可以跳过nil值并且顺序不重要,那么切换到pairs将更容易。

2011-08-25 01:14:25
stackoverflow用户221509
stackoverflow用户221509

实际上,在 varargs 中处理 nil 值非常容易,您只需要使用 select 函数即可(它甚至适用于 nil(它计算实际参数数量)。以下惯用法非常有用,以至于它是 Lua 5.2 中的核心库函数 table.pack

function table.pack(...)
  return { n = select("#", ...), ... }
end

参数数量存储在字段 n 中,因此为了遍历它们,只需使用这个:

function vararg(...)
    local args = table.pack(...)
    for i=1,args.n do
        -- do something with args[i], careful, it might be nil!
    end
end
2011-08-25 07:52:21