26

我试图验证一个变量不等于这个或那个。我尝试使用以下代码,但都不起作用:

if x ~=(0 or 1) then
    print( "X must be equal to 1 or 0" )
    return
end


if x ~= 0 or 1 then
    print( "X must be equal to 1 or 0" )
    return
end

有没有办法做到这一点?

4

3 回答 3

59

您的问题源于对or学习此类编程语言的人常见的运算符的误解。是的,您的直接问题可以通过写作来解决x ~= 0 and x ~= 1,但我将更详细地说明您尝试的解决方案为何不起作用。

当您阅读x ~=(0 or 1)x ~= 0 or 1很自然地解析它时,就像句子“x 不等于零或一”一样。在对该语句的通常理解中,“x”是主语,“不等于”是谓词或动词短语,“零或一”是宾语,是由连词连接的一组可能性。您将带有动词的主语应用于集合中的每个项目。

但是,Lua 并没有根据英语语法规则来解析它,它会根据操作顺序对两个元素进行二进制比较来解析它。每个运算符都有一个优先级,该优先级决定了对其进行评估的顺序。 or的优先级低于~=,就像数学中加法的优先级低于乘法一样。一切的优先级都低于括号。

结果,在评估 时x ~=(0 or 1),解释器将首先计算0 or 1(因为括号),然后x ~=是第一个计算的结果,在第二个示例中,它将计算x ~= 0然后将该计算的结果应用到or 1

逻辑运算符or“如果此值不同于 nil 和 false,则返回其第一个参数;否则,或返回其第二个参数”。关系运算符~=是等式运算符的逆==;如果它的参数是不同的类型(x一个数字,对吗?),它返回 true,否则正常比较它的参数。

使用这些规则,x ~=(0 or 1)将分解为x ~= 0(在应用or运算符之后),如果 x 不是 0,包括 1,这将返回“真”,这是不希望的。另一种形式, x ~= 0 or 1将首先评估x ~= 0(可能返回真或假,取决于 x 的值)。然后,它将分解为false or 1或 之一true or 1。在第一种情况下,语句将返回1,在第二种情况下,语句将返回true。因为 Lua 中的控制结构只考虑nilandfalse为假,而其他任何东西都为真,这总是会进入if语句,这也不是你想要的。

您无法使用编程语言中提供的二元运算符将单个变量与值列表进行比较。相反,您需要将变量与每个值一一进行比较。有几种方法可以做到这一点。最简单的方法是使用德摩根定律将语句“非一或零”(不能用二元运算符评估)表示为“非一非零”,这可以用二元运算符轻松编写:

if x ~= 1 and x ~= 0 then
    print( "X must be equal to 1 or 0" )
    return
end

或者,您可以使用循环来检查这些值:

local x_is_ok = false
for i = 0,1 do 
    if x == i then
        x_is_ok = true
    end
end
if not x_is_ok then
    print( "X must be equal to 1 or 0" )
    return
end

最后,您可以使用关系运算符来检查范围,然后测试 x 是否是范围内的整数(您不想要 0.5,对吗?)

if not (x >= 0 and x <= 1 and math.floor(x) == x) then
    print( "X must be equal to 1 or 0" )
    return
end

请注意,我写了x >= 0 and x <= 1. 如果你理解了上面的解释,你现在应该可以解释我为什么不写0 <= x <= 1了,以及这个错误的表达会返回什么!

于 2012-07-25T22:44:54.743 回答
10

为了只测试两个值,我个人会这样做:

if x ~= 0 and x ~= 1 then
    print( "X must be equal to 1 or 0" )
    return
end

如果您需要针对两个以上的值进行测试,我会将您的选择塞入一个像集合一样的表格中,如下所示:

choices = {[0]=true, [1]=true, [3]=true, [5]=true, [7]=true, [11]=true}

if not choices[x] then
    print("x must be in the first six prime numbers")
    return
end
于 2012-07-25T21:46:12.063 回答
5

x ~= 0 or 1是相同的((x ~= 0) or 1)

x ~=(0 or 1)是一样的(x ~= 0)

尝试这样的事情。

function isNot0Or1(x)
    return (x ~= 0 and x ~= 1)
end

print( isNot0Or1(-1) == true )
print( isNot0Or1(0) == false )
print( isNot0Or1(1) == false )
于 2012-07-25T21:47:43.693 回答