定义函数参数的默认值

时间:2011-05-16 19:47:23

标签: function lua

在Lua wiki中,我找到了一种为缺失参数定义默认值的方法:

function myfunction(a,b,c)
    b = b or 7
    c = c or 5
    print (a,b,c)
end

这是唯一的方法吗? PHP样式myfunction (a,b=7,c=5)似乎不起作用。并不是说Lua方式不起作用,我只是想知道这是否是唯一的方法。

6 个答案:

答案 0 :(得分:77)

如果你想要命名参数和默认值,如PHP或Python,你可以使用表构造函数调用你的函数:

myfunction{a,b=3,c=2}

(在Lua的许多地方都可以看到这种情况,例如the advanced forms of LuaSocket's protocol modulesIUPLua中的构造函数。)

函数本身可以有这样的签名:

function myfunction(t)
    setmetatable(t,{__index={b=7, c=5}})
    local a, b, c =
      t[1] or t.a, 
      t[2] or t.b,
      t[3] or t.c
    -- function continues down here...
end

参数表中缺少的任何值都将从其metatable中的__index表中获取(参见the documentation on metatables)。

当然,使用表构造函数和函数可以实现更高级的参数样式 - 您可以编写所需的任何内容。例如,here是一个函数,它构造一个函数,该函数从定义参数名称和默认值的表以及带有常规参数列表的函数中获取命名或位置参数表。

作为非语言级别的功能,可以更改此类调用以提供新的行为和语义:

  • 可以使变量接受多个名称
  • 位置变量和关键字变量可以穿插 - 并且定义两者都可以优先于(或导致错误)
  • 可以制作仅关键字无位置变量,以及无名无位置变量
  • 可以通过解析字符串
  • 来完成相当详细的表格构造
  • 如果使用1 table
  • 以外的函数调用函数,则可以逐字使用参数列表

编写参数翻译器的一些有用函数是unpack(在5.2中移至table.unpacksetfenv(在5.2中不推荐使用新的_ENV构造),以及{ {1}}(从给定的参数列表返回单个值,或者使用select返回列表的长度)。

答案 1 :(得分:44)

在我看来,没有其他办法。这只是Lua的心态:没有多余的装饰,除了一些语法糖,没有多余的方法做简单的事情。

答案 2 :(得分:20)

从技术上讲,有b = b == nil and 7 or b(在false是有效值的情况下应该使用false or 7评估为7),但这可能不是你想要的

答案 3 :(得分:5)

到目前为止我发现的唯一有意义的方法是做这样的事情:

function new(params)
  params = params or {}
  options = {
    name = "Object name"
  }

  for k,v in pairs(params) do options[k] = v end

  some_var = options.name
end

new({ name = "test" })
new()

答案 4 :(得分:1)

如果您的函数不希望将布尔值 falsenil 作为参数值传递,那么您建议的方法是好的:

function test1(param)
  local default = 10
  param = param or default
  return param
end

--[[
test1(): [10]
test1(nil): [10]
test1(true): [true]
test1(false): [10]
]]

如果您的函数允许将布尔值 false 而不是 nil 作为参数值传递,您可以按照 {{3} 的建议检查 nil 是否存在},只要默认值不是布尔值false

function test2(param)
  local default = 10
  param = (param == nil and default) or param
  return param
end

--[[
test2(): [10]
test2(nil): [10]
test2(true): [true]
test2(false): [false]
]]

当默认值为布尔值 false 时,上述方法中断:

function test3(param)
  local default = false
  param = (param == nil and default) or param
  return param
end

--[[
test3(): [nil]
test3(nil): [nil]
test3(true): [true]
test3(false): [false]
]]

有趣的是,颠倒条件检查的顺序确实允许布尔值 false 成为默认值,并且名义上性能更高:

function test4(param)
  local default = false
  param = param or (param == nil and default)
  return param
end

--[[
test4(): [false]
test4(nil): [false]
test4(true): [true]
test4(false): [false]
]]

这种方法的工作原理似乎违反直觉,直到进一步检查,发现它们有点聪明。

如果您希望do允许传递nil值的函数的默认参数,您需要做一些更丑陋的事情,例如使用可变参数:

function test5(...)
  local argN = select('#', ...)
  local default = false
  local param = default
  if argN > 0 then
    local args = {...}
    param = args[1]
  end
  return param
end

--[[
test5(): [false]
test5(nil): [nil]
test5(true): [true]
test5(false): [false]
]]

当然,可变参数完全阻止使用它们的函数中函数参数的自动完成和 linting。

答案 5 :(得分:1)

简短的回答是它是最简单和最好的方法。在 lua 中,变量默认等于 nil 。这意味着如果我们不向 lua 函数传递参数,参数是 exits 而是 nil 并且 lua 程序员使用这个 lua 属性来设置默认值。

这也不是设置默认值的方法,但您可以使用以下函数

这个函数创建一个错误是你没有将值传递给参数

function myFn(arg1 , arg2)
err = arg1 and arg2
if not err then error("argument") end
-- or
if not arg1 and arg2 then error("msg") end

但这不是一个好方法,最好不要使用此功能

并在图表中显示 [,arg] 中的可选参数

function args(a1 [,a2])
-- some
end
function args ( a1 [,a2[,a3]])
-- some
end