我正在尝试验证变量不等于这个或那个。我尝试使用以下代码,但都不起作用:
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
有办法做到这一点吗?
答案 0 :(得分:47)
您的问题源于对or
运算符的误解,这对于学习这样的编程语言的人来说很常见。是的,您可以通过撰写x ~= 0 and x ~= 1
来解决您的直接问题,但我会详细介绍您的尝试解决方案无效的原因。
当您阅读x ~=(0 or 1)
或x ~= 0 or 1
时,解析此问题是很自然的,因为句子“x不等于零或一”。在对该陈述的普通理解中,“x”是主语,“不等于”是谓词或动词短语,而“零或一”是对象,一组由连词加入的可能性。您将带有动词的主题应用于集合中的每个项目。
然而,Lua并没有根据英语语法规则对其进行解析,它根据其操作顺序在两个元素的二进制比较中对其进行解析。每个运算符都有一个precedence,用于确定评估的顺序。 or
的优先级低于~=
,正如数学中的加法优先级高于乘法。一切都优先于括号。
因此,在评估x ~=(0 or 1)
时,解释器将首先计算0 or 1
(因为括号),然后计算x ~=
第一次计算的结果,并在第二个示例中,它将计算x ~= 0
,然后将该计算的结果应用于or 1
。
如果此值与nil和false不同,则logical operator or
“返回其第一个参数;否则,返回其第二个参数”。 relational operator ~=
是等于运算符==
的反函数;如果它的参数是不同的类型(x 是一个数字,对吧?),它返回true,否则通常比较它的参数。
使用这些规则,x ~=(0 or 1)
将分解为x ~= 0
(在应用or
运算符后),如果x为0以外的任何值,则返回“true”,包括1,不受欢迎。另一种形式x ~= 0 or 1
将首先评估x ~= 0
(可能会返回true或false,具体取决于x的值)。然后,它将分解为false or 1
或true or 1
之一。在第一种情况下,语句将返回1
,在第二种情况下,语句将返回true
。因为Lua中的控制结构只考虑nil
和false
是假的,而其他任何事情都是真的,所以它总是会输入if
语句,这也不是你想要的。< / p>
您无法使用编程语言中提供的二元运算符将单个变量与值列表进行比较。相反,您需要逐个将变量与每个值进行比较。有几种方法可以做到这一点。最简单的方法是使用De Morgan's laws将语句'not one or zero'(不能用二元运算符计算)表示为'not one and not zero',这可以简单地用二元运算符编写:
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
,以及这个错误表达会返回什么!
答案 1 :(得分:9)
仅测试两个值,我个人会这样做:
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
答案 2 :(得分:4)
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 )