在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方式不起作用,我只是想知道这是否是唯一的方法。
答案 0 :(得分:77)
如果你想要命名参数和默认值,如PHP或Python,你可以使用表构造函数调用你的函数:
myfunction{a,b=3,c=2}
(在Lua的许多地方都可以看到这种情况,例如the advanced forms of LuaSocket's protocol modules和IUPLua中的构造函数。)
函数本身可以有这样的签名:
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是一个函数,它构造一个函数,该函数从定义参数名称和默认值的表以及带有常规参数列表的函数中获取命名或位置参数表。
作为非语言级别的功能,可以更改此类调用以提供新的行为和语义:
编写参数翻译器的一些有用函数是unpack
(在5.2中移至table.unpack
,setfenv
(在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)
如果您的函数不希望将布尔值 false
或 nil
作为参数值传递,那么您建议的方法是好的:
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