在Lua中,处理包含nil的可变参数的正确方法是什么?

发布于 2024-12-01 10:19:34 字数 427 浏览 1 评论 0原文

我正在尝试创建一个调试打印函数,它将文件句柄作为第一个参数。首先,我编写一个如下所示的函数:

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)
=> prints only 1 and 2

那么,解决这个问题的正确方法是什么?

I'm trying to create a debug print function which takes a file handle as the first argument. First, I write a function like this:

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

This function works as long as I don't pass nil value in arguments. But if I call this with a nil, it doesn't print the nil value and rest of arguments.

fprint(io.stderr, 1, 2, nil, 3)
=> prints only 1 and 2

So, what is the right way to fix this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

简单 2024-12-08 10:19:34

实际上,处理 varargs 中的 nil 值很容易,您所需要做的就是使用 select 函数,即使使用 nil 也能工作(它计算参数的实际数量)。下面的习惯用法非常有用,它是一个核心库函数 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

Actually, it's easy to handle nil values in varargs, all you need is to use the select function, which works even with nil (it counts the actual number of parameters). The following idiom is so useful that it is a core library function table.pack in Lua 5.2:

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

The number of arguments is stored in field n, so in order to iterate through them just use this:

function vararg(...)
    local args = table.pack(...)
    for i=1,args.n do
        -- do something with args[i], careful, it might be nil!
    end
end
心是晴朗的。 2024-12-08 10:19:34

据我所知,没有简单的独立于实现的方法来知道包含 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 会容易得多。

As best I know, there's no easy implementation independent way to know the length of an array that contains nil entries since the # operation can point to any position that is followed by a nil, but this is a quick implementation dependent solution that will print the nil.

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

Rather than relaying on #, you can get complicated (and therefore implementation independent) since you know the parm table is an array and use something like this:

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

If you can skip the nil values and order isn't important, then switching to pairs would be much easier.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文