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() を呼び出すと、変数は false になります。<= は、両方が NaN の場合に true になる可能性がありますが、「最初に」数値として存在する必要があるため、両方とも数値である必要があり、比較によって if ステートメントが短絡することはありません。if が失敗した場合は、次の有効な戻り値までスキップします。良さそう?誰でも問題が見られますか?

4

2 に答える 2

4

数値を nil と比較するとエラーになるため、 が数値で nilfirstの場合、コードが壊れます。secondより正しいバージョンは次のとおりです。

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 に答える