我没有在函数定义中使用长参数列表,而是更喜欢传递一些固定参数和一个"附加参数"表,如下所示:
function:doit( text, params )
end
Run Code Online (Sandbox Code Playgroud)
这很好,因为它允许我以后添加新的命名参数而不会破坏旧的调用.
当我尝试强制某些参数的默认值时,我遇到的问题出现了:
function:doit( text, params )
local font = params.font or native.systemBold
local fontSize = params.fontSize or 24
local emboss = params.emboss or true
-- ...
end
Run Code Online (Sandbox Code Playgroud)
上面的代码在所有情况下都可以正常工作,除非我通过'false'进行浮雕:
doit( "Test text", { fontSize = 32, emboss = false } )
Run Code Online (Sandbox Code Playgroud)
当我真的想要假时,上面的代码将导致浮雕设置为true.
要清楚,我想要的是将第一个非NIL值分配给浮雕,而不是我得到第一个非假和非NIL.
为了解决这个问题,我编写了一小段代码来查找表中的第一个非NIL值并返回:
function firstNotNil( ... )
for i = 1, #arg do
local theArg = arg[i]
if(theArg ~= nil) then return theArg end
end
return nil
end
Run Code Online (Sandbox Code Playgroud)
使用此函数,我将重写浮雕赋值如下:
local emboss = firstNotNil(params.emboss, true)
Run Code Online (Sandbox Code Playgroud)
现在,这肯定有效,但它似乎效率低下而且超过顶部.我希望有一种更紧凑的方式来做到这一点.
请注意:我发现这个看起来很有前途的红宝石结构,我希望lua有类似的东西:
[c,b,a].detect { |i| i > 0 } -- Assign first non-zero in order: c,b,a
Run Code Online (Sandbox Code Playgroud)
Lua的关系运算符计算其中一个操作数的值(即该值不被强制转换为boolean),因此您可以通过说明获得C的三元运算符的等价物a and b or c.在你的情况下,你想要使用,a如果不是nil,b否则,所以a == nil and b or a:
local emboss = (params.emboss == nil) and true or params.emboss
Run Code Online (Sandbox Code Playgroud)
不像以前那么漂亮,但你只需要为布尔参数做这件事.
[snip - Lua代码]
现在,这肯定有效,但它似乎效率低下而且超过顶部.
请注意:我发现这个看起来很有前途的红宝石结构,我希望lua有类似的东西:
[c,b,a] .detect {| i | i> 0} - 按顺序分配第一个非零:c,b,a
你的Lua功能不再是过顶或低效.就源文本而言,Ruby构造更简洁,但语义并没有真正的不同firstNotNil(c,b,a).这两个构造最终都会创建一个列表对象,使用一组值对其进行初始化,然后通过线性搜索列表的函数运行该列表对象.
在Lua中,您可以使用vararg表达式跳过列表对象的创建select:
function firstNotNil(...)
for i = 1, select('#',...) do
local theArg = select(i,...)
if theArg ~= nil then return theArg end
end
return nil
end
Run Code Online (Sandbox Code Playgroud)
我希望有一种更紧凑的方式来做到这一点.
关于这样做的唯一方法是缩短函数名称.;)