3

我有一个可以使用 0、1 或 2 个参数调用的函数。我想测试一下输入了多少参数以及它们是否是实际数字。这是代码:

first = tonumber(frame.args[1])
second = tonumber(frame.args[2])

if first then
  if first <= second then
    return math.random(first, second)
  end
return math.random(first)
end   
return math.random()

我的想法是,如果它们不是数字(或为空),那么当我调用 tonumber() 时,变量将为假。如果它们都是 NaN,则 <= 可能为真,但它们必须经历作为数字存在的“第一个”,因此它们都必须是数字,并且比较不会使 if 语句短路。如果任何一个 if 失败,它就会跳到下一个有效的返回。看起来不错?有人看到任何问题吗?

4

2 回答 2

4

first如果是数字并且为 nil,则您的代码会中断second,因为将数字与 nil 进行比较是错误的。这是一个更正确的版本:

first = tonumber(frame.args[1])
second = tonumber(frame.args[2])

if second and first and (first <= second) then
  return math.random(first, second)
elseif first then
  return math.random(first)
else return math.random() end

然而,这段代码非常脆弱:它不检查参数的类型,也不确保数字是整数。根据它的用途,您可能希望使其更严格。一个非常严格的版本看起来像:

local is_int = function(n)
  return (type(n) == "number") and (math.floor(n) == n)
end

local first, second = frame.args[1], frame.args[2]

if first == nil then
  assert(second == nil)
  return math.random()
else
  assert(is_int(first))
  if second == nil then
    return math.random(first)
  else
    assert(is_int(second))
    return math.random(first,second)
  end
end

当然,您也可以决定返回nil意外输入而不是使用断言...

于 2013-02-21T11:17:54.397 回答
1

如果可以接受包含数字的字符串,tonumber(foo)则可以正常工作,并且实际上会在内部将其转换为“数字”值。但是,如果您需要知道 Lua 是否将其视为实际数字而不是字符串,'number' == type(foo)请在您的测试条件中使用。

于 2013-02-21T07:46:05.157 回答