LUA: 寻求高效且无误的默认参数赋值方式
我喜欢在函数定义中传入几个固定的参数和一个“额外参数”的表,而不是使用长长的参数列表,像这样:
function:doit( text, params )
end
这样很好,因为它允许我稍后添加新的命名参数而不破坏旧的调用。
我现在遇到的问题是当我尝试强制一些参数的默认值时,就会出现问题:
function:doit( text, params )
local font = params.font or native.systemBold
local fontSize = params.fontSize or 24
local emboss = params.emboss or true
-- ...
end
上面的代码在所有情况下都可以正常工作,除非我传入了'false'来控制浮雕:
doit( "Test text", { fontSize = 32, emboss = false } )
上面的代码将导致 emboss 被设置为 true ,而我实际上想要 false 。
要明确这一点,我想要的是将第一个非 NIL 值赋给 emboss ,但我得到的是第一个非 false 和 non-NIL 的值。
为了解决这个问题,我写了一小段代码来找到表中第一个非 NIL 值并返回它:
function firstNotNil( ... )
for i = 1, #arg do
local theArg = arg[i]
if(theArg ~= nil) then return theArg end
end
return nil
end
使用这个函数,我会将 emboss 赋值重写为:
local emboss = firstNotNil(params.emboss, true)
现在,这当然是有效的,但它似乎太低效和繁琐了。我希望有一种更紧凑的方法来实现这一点。
请注意:我发现了这个看起来很有前途的 ruby 构造方法,我希望 lua 有类似的功能:
[c,b,a].detect { |i| i > 0 } --将按顺序分配第一个非零值:c,b,a
Lua 的关系运算符返回一个操作数的值(即值不会被强制转换为布尔值),因此可以通过 a and b or c 表达式来获取与 C 中三目运算符等效的结果。在您的情况中,如果 a 不为 nil,则使用 a,否则使用 b,因此表达式为 a == nil and b or a:
local emboss = (params.emboss == nil) and true or params.emboss
虽然不像以前那么漂亮,但您只需要为布尔参数执行此操作。
[snip - Lua code]
现在,这当然起作用,但它似乎非常低效和浪费,因为定义了一个单独的函数来做这件事。
请注意:我发现这个 Ruby 构造,看起来很有前途,我希望 Lua 也有类似的东西:
[c,b,a].detect { |i| i > 0 } -- Assign first non-zero in order: c,b,a
您的 Lua 函数并不比 Ruby 构造更浪费或低效。Ruby 构造在源代码上更加简洁,但语义与 firstNotNil(c,b,a) 并没有什么区别。这两个构造都会创建一个列表对象,将其初始化为一组值,并运行通过线性搜索列表的函数。
在 Lua 中,您可以使用 select 的可变参数表达式跳过创建列表对象:
function firstNotNil(...)
for i = 1, select('#',...) do
local theArg = select(i,...)
if theArg ~= nil then return theArg end
end
return nil
end
我希望有更紧凑的方法来实现这个功能。
唯一的方法就是缩短函数名。 ;)
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
如果你真的想要在一行中完成,你需要像这样设置默认值为 true :
local emboss = params.emboss or (params.emboss == nil)这并不是非常易读,但是它能起作用。当 params.emboss 没有被设置(当你需要一个默认值时)时,(params.emboss == nil) 的值为 true,否则值为 false。所以当 params.emboss 为 false 时,这个语句为 false,而当它为 true 时,这个语句为 true (true or false = true)。
对于一个默认值为 false 的情况,你最初尝试的也可以工作:
local emboss = params.emboss or false