我正在尝试验证变量是否不等于
0
或 1
。我尝试使用以下方法,但都不起作用:
if x ~= (0 or 1) then
print("x is not equal to 1 or 0")
end
if x ~= 0 or 1 then
print("x is not equal to 1 or 0")
end
相反,以这种方式使用
==
也不起作用:
if x == (0 or 1) then
print("x is equal to 1 or 0")
end
if x == 0 or 1 then
print("x is equal to 1 or 0")
return
end
有办法做到这一点吗?
您的问题源于对
or
运算符的误解,这对于学习此类编程语言的人来说很常见。是的,您眼前的问题可以通过写 x ~= 0 and x ~= 1
来解决,但我将更详细地说明为什么您尝试的解决方案不起作用。
当您阅读
x ~=(0 or 1)
或 x ~= 0 or 1
时,很自然地会像解析“x 不等于 0 或 1”这句话一样解析它。在对该陈述的通常理解中,“x”是主语,“不等于”是谓语或动词短语,“零或一”是宾语,是由连词连接的一组可能性。您将主语和动词应用于集合中的每个项目。
然而,Lua 并不是根据英语语法规则来解析它,而是根据其操作顺序通过两个元素的二进制比较来解析它。每个运算符都有一个“优先级”,它决定了它的计算顺序。 or
的优先级低于
~=
,就像数学中加法的优先级低于乘法一样。所有内容的优先级都低于括号。 因此,在计算
x ~=(0 or 1)
时,解释器将首先计算
0 or 1
(因为括号的原因),然后计算 x ~=
第一次计算的结果,在第二个示例中,它将计算 x ~= 0
和然后将该计算的结果应用于 or 1
。逻辑运算符
or
“如果该值不同于 nil 和 false,则返回其第一个参数;否则,返回其第二个参数”。
关系运算符
~=
是相等运算符 ==
的逆运算符;如果它的参数是不同类型(x is是一个数字,对吗?),它返回 true,否则正常比较它的参数。使用这些规则,
x ~=(0 or 1)
将分解为x ~= 0
(在应用
or
运算符之后),如果x是0以外的任何值(包括1),这将返回“true”,这是不希望的。另一种形式,
x ~= 0 or 1
将首先评估
x ~= 0
(可能返回 true 或 false,具体取决于 x 的值)。然后,它会分解为
false or 1
或
true or 1
之一。在第一种情况下,该语句将返回
1
,在第二种情况下,该语句将返回
true
。因为 Lua 中的控制结构只认为
nil
和
false
为假,而其他任何东西都为真,所以这总是会进入
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
,以及这个错误的表达式会返回什么!为了仅测试两个值,我个人会这样做:
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
((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 )