首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LUA:寻求有效且无错误的赋值默认参数的方法

LUA:寻求有效且无错误的赋值默认参数的方法
EN

Stack Overflow用户
提问于 2012-07-03 01:53:06
回答 2查看 610关注 0票数 6

与在函数定义中使用长长的参数列表相比,我更喜欢传递一些固定的参数和一个包含“附加参数”的表,如下所示:

代码语言:javascript
复制
function:doit( text, params )
end

这很好,因为它允许我稍后添加新的命名参数,而不会中断旧的调用。

当我试图强制某些参数的默认值时,我遇到的问题发生了:

代码语言:javascript
复制
function:doit( text, params )
   local font     = params.font or native.systemBold 
   local fontSize = params.fontSize or 24
   local emboss   = params.emboss or true

   -- ...

end

上面的代码在所有情况下都工作得很好,除了我为emboss传入了'false‘:

代码语言:javascript
复制
doit( "Test text", { fontSize = 32, emboss = false } )

当我真的想要false时,上面的代码会导致emboss被设置为true。

需要明确的是,我想要的是将第一个非NIL值赋给emboss,而我得到的是第一个非false和非NIL的值。

为了解决这个问题,我编写了一小段代码来查找表中的第一个非空值,并返回该值:

代码语言:javascript
复制
function firstNotNil( ... )
   for i = 1, #arg do
      local theArg = arg[i]
      if(theArg ~= nil) then return theArg end
   end
   return nil
end

使用此函数,我将重写浮雕赋值,如下所示:

代码语言:javascript
复制
   local emboss   = firstNotNil(params.emboss, true)

现在,这当然是有效的,但它似乎是如此的低效和过度。我希望有一种更紧凑的方法来做这件事。

请注意:我发现了这个红宝石构造,它看起来很有前途,我希望lua有类似的东西:

代码语言:javascript
复制
[c,b,a].detect { |i| i > 0 } -- Assign first non-zero in order: c,b,a
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-03 05:50:18

Lua的关系运算符的计算结果是其中一个操作数的值(即该值不会被强制转换为布尔值),因此您可以通过输入a and b or c来获得与C的三元运算符等效的值。在您的示例中,如果不是nil,则使用a,否则使用b,因此使用a == nil and b or a

代码语言:javascript
复制
local emboss = (params.emboss == nil) and true or params.emboss

不像以前那么漂亮了,但您只需要对布尔参数执行此操作。

snip - Lua代码

现在,这当然是有效的,但它似乎是如此的低效和过度。

请注意:我发现了这个红宝石构造,它看起来很有前途,我希望lua有类似的东西:

c,b,a.detect { |i| i>0} --按顺序分配第一个非零数: c,b,a

您的Lua函数不再过度或低效。就源文本而言,Ruby结构更简洁,但其语义与firstNotNil(c,b,a)并没有什么不同。这两个构造最终都创建了一个列表对象,使用一组值对其进行初始化,并通过一个线性搜索列表的函数运行该对象。

在Lua中,您可以通过在select中使用vararg表达式来跳过列表对象的创建

代码语言:javascript
复制
function firstNotNil(...)
   for i = 1, select('#',...) do
      local theArg = select(i,...)
      if theArg ~= nil then return theArg end
   end
   return nil
end

我希望有一种更简洁的方法来做这件事。

要做到这一点,唯一的方法是缩短函数名。;)

票数 9
EN

Stack Overflow用户

发布于 2012-07-03 03:17:18

如果您真的想在一行中完成此操作,则需要类似下面这样的内容作为默认值true

代码语言:javascript
复制
local emboss   = params.emboss or (params.emboss == nil)

它的可读性不是很好,但它是有效的。(params.emboss == nil)在未设置params.emboss时(当需要默认值时)计算为true,否则为false。因此,当params.emboss为false时,语句为false;当为true时,语句为true (true或false = true)。

对于默认的false,您最初尝试的内容将会起作用:

代码语言:javascript
复制
local emboss   = params.emboss or false
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11298660

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档