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()。如果boolfunc1() 都为真,它只会返回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

首先将评估 boolfunc1()。 如果bool 不为真,Lua 不必调用func1(),因为表达式永远不会为真。 所以 Lua 可以马上去评估func2()。 您的函数将返回 func2()!

相反,如果booltrue,Lua 会调用func1() 来查看它是否也是true。 如果func1() 返回true,Lua 将不会调用func2()。由于以下or,如果boolfunc1()true,则表达式将始终为true。 如果 func1() 返回 false/nil,则必须评估 or。所以 Lua 也会调用func2(),然后返回它的返回值。

了解运算符的优先级以及在何种情况下 Lua 会中止计算表达式,这一点很重要!

Lua 的orand 运算符使用快捷方式求值。仅在必要时评估第二个操作数

【讨论】:

那么,第二个和第三个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

如果你使用不带括号的func1func2,你会得到一个函数对象,并且函数对象在 Lua 中总是被评估为真。 (在 Lua 中被评估为 false 的只有 falsenil。)

【讨论】:

【参考方案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 中的三元运算符(函数)的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS:三元运算符条件检查中的函数调用

For循环中的三元运算符导致无限迭代

三元运算符如何比较 JavaScript 中的字符和数字?

带有对象的Javascript三元运算符

三元表达式是啥?

箭头函数内的三元运算符