Lua 中的三元运算符(函数)
Posted
技术标签:
【中文标题】Lua 中的三元运算符(函数)【英文标题】:Ternary operators in Lua (function) 【发布时间】:2018-04-03 15:07:35 【问题描述】:我在代码战中遇到了这个问题,如下所示:
实现一个函数,该函数将根据一个布尔值运行 2 个不同的函数。当然,也可以使用简单的 if 语句来实现。像这样:
function _if(bool, func1, func2)
if bool then return func1() else return func2() end
end
但是,当我想使用三元运算符解决它时,它并没有通过所有测试用例:
function _if(bool, func1, func2)
return bool and func1() or func2()
end
但这有效:
function _if(bool, func1, func2)
return (bool and func1 or func2)()
end
我认为我对 Lua 的了解不够。我已经在社区中搜索过这个问题,但找不到任何明确的解释。我想知道是否有人可以对此有所了解,或者只是建议一些可能有助于我理解的文章。
更新 编辑
那么,如果func1
总是返回真值,那么第二个 sn-p 与第三个有何不同?
【问题讨论】:
Lua 没有任何三元运算符!就是这样,优先级高于or。 看我的回答。我添加了一些细节。请阅读en.wikipedia.org/wiki/Short-circuit_evaluation 【参考方案1】:function _if(bool, func1, func2)
if bool then return func1() else return func2() end
end
如果 bool 为真,上述代码返回 func1(),否则返回 func2()。
如果bool
不为真或bool
为真且func1()
不为真,则以下代码将返回func2()
。如果bool
和func1()
都为真,它只会返回func1()
。
function _if(bool, func1, func2)
return bool and func1() or func2()
end
如果 bool 为真,最后一段代码将返回 func1(),否则返回 func2()。
function _if(bool, func1, func2)
return (bool and func1 or func2)()
end
首先,Lua 没有任何三元运算符。巧妙地使用 and 的优先级高于 or 就相当于 C 中的三元运算符 ?:
第二个表达式a = b and c or d
只有在 c 为真时才能正常工作。如果您将函数调用用作 c,则情况可能并非总是如此。
这是一种方便的分配方式,但在许多情况下,它增加了可读性并减少了错误,只需坚持使用 if else 语句。
一旦你必须添加更多的条件,and/trick 就会变得一团糟。
那么让我们再看看第二个 sn-p 中发生了什么。
function _if(bool, func1, func2)
return bool and func1() or func2()
end
首先将评估 bool
和 func1()
。
如果bool
不为真,Lua 不必调用func1()
,因为表达式永远不会为真。
所以 Lua 可以马上去评估func2()
。
您的函数将返回 func2()
!
相反,如果bool
是true
,Lua 会调用func1()
来查看它是否也是true
。
如果func1()
返回true
,Lua 将不会调用func2()
。由于以下or
,如果bool
和func1()
为true
,则表达式将始终为true
。
如果 func1()
返回 false/nil,则必须评估 or
。所以 Lua 也会调用func2()
,然后返回它的返回值。
了解运算符的优先级以及在何种情况下 Lua 会中止计算表达式,这一点很重要!
Lua 的or
和and
运算符使用快捷方式求值。仅在必要时评估第二个操作数
【讨论】:
那么,第二个和第三个sn-p有什么明显的区别吗? 是的。第三个 sn-p 将根据 bool 的值调用 func1 或 func2 并返回相应的返回值。如果它不是真的,第二个 sn-p 将永远不会返回 func1 的返回值。它将返回 func2 的返回值。并且您将始终在第二个 sn-p 中调用 func1。而第三个 sn-p 只调用其中一个函数 所以在第二个 sn-p 中,如果 bool 为真,则 func1() 将被调用并给 func1() 返回真值,它会停在那里。如果 bool 是假的 func2() 会被调用,对吗? @AndyAldo 是的,如果 bool 为真但 func1() 返回 nil/false 也会调用 func2,所以最好坚持使用第三个 sn-p 或使用 if/else【参考方案2】:如果您查看仅使用or
时会发生什么,也许它会帮助您了解正在发生的事情。
function func1()
return true
end
function func2()
return false
end
print(func1() or "default") -- true
print(func1 or "default") -- function: 0x2377c80
print(func2() or "default") -- default
print(func2 or "default") -- function: 0x2377cb0
如果你使用不带括号的func1
或func2
,你会得到一个函数对象,并且函数对象在 Lua 中总是被评估为真。 (在 Lua 中被评估为 false 的只有 false
和 nil
。)
【讨论】:
【参考方案3】:您的代码中有几个潜在的问题。
1. 如前所述,如果func1
返回任何falsy
值,则将调用func2
。
2. bool and func1() or func2()
只返回一个结果。
【讨论】:
你能解释一下第二个和第三个有什么不同吗?local fn = cond and f1 or f2; return fn()
与 local ret = cond and f1(); if not ret then ret = f2() end; return ret
【参考方案4】:
if
版本不等同于使用and
的第二个版本
如果 func1() 返回 false,则评估 or
部分并返回 func2() 的结果。
最后一个有效(当 func1 不是 nil
时),因为您在确定要调用哪个函数之后调用该函数。因此,bool
只需选择指向下一个要调用的函数的“指针”。假设func1
不是nil
,则指针永远不会为假。
【讨论】:
那么,第二个和第三个sn-p有什么明显的区别吗? 第二个首先调用函数func1,根据func1()的结果是真还是假来决定是否进行OR。第三个决定要使用的函数,无论是func1还是func2,但直到做出决定后才调用它。以上是关于Lua 中的三元运算符(函数)的主要内容,如果未能解决你的问题,请参考以下文章