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