Lua 中的三元运算符(函数)

Ternary operators in Lua (function)

我在 codewars 中遇到这个问题是这样的:

实现一个函数,该函数将 运行 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 总是 return 真实值,那么第二个片段与第三个片段有何不同?

if 版本不等同于使用 and

的第二个版本

如果 func1() returns 为假,则计算 or 部分并返回 func2() 的结果。

最后一个有效(当 func1 不是 nil 时),因为您在确定调用哪个函数后调用该函数。因此,bool 只需选择 'pointer' 下一个要调用的函数。假设 func1 不是 nil,指针永远不会是假的。

您的代码中存在几个潜在问题。 1. 如前所述,如果 func1 returns 任何 falsy 值,则 func2 将被调用。 2. bool and func1() or func2() returns 正好一个结果。

function _if(bool, func1, func2) 
    if bool then return func1() else return func2() end
end

上面的代码 returns func1() if bool is true and func2() else.

如果 bool 不为真,或者 bool 为真且 func1() 不为真,则以下代码将 return func2()。如果 boolfunc1() 都为真,它只会 return func1()

function _if(bool, func1, func2) 
    return bool and func1() or func2()
end

如果 bool 为真,最后一段代码将 return 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 or 技巧就会变得一团糟。

那么让我们再看看第二个片段中发生了什么。

function _if(bool, func1, func2) 
    return bool and func1() or func2()
end

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

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

了解运算符优先级很重要,在这种情况下 Lua 将中止表达式的计算!

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

如果您查看仅使用 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。)