17

Ruby 是否有一个简单的英语关键字来表示独占或,就像他们有“and”和“or”一样?如果不是,这是因为排他性还是不允许评估捷径?

4

7 回答 7

24

不,它没有,您只能使用^.

不知道为什么没有特别的,可能只是因为它不常用。

于 2009-02-25T08:55:16.500 回答
18

我遇到了一个问题,因为 '^' 运算符按位对数字起作用,

true ^ 1
=> false

1 ^ true
TypeError: can't convert true into Integer
true ^ 1

所以我的解决方法是:

( !!a ^ !!b )双爆炸将它们强制转换为布尔值。

!!1 ^ !!true
=> false

!!1 ^ !!false
=> true
于 2009-06-29T14:03:40.917 回答
13

首先,我认为短路不适用于 XOR:无论第一个操作数的值如何,都需要检查第二个操作数。

其次,and, &&, or and || 在所有情况下都使用短路;“单词”和“符号”版本之间的唯一区别是优先级。我相信and并且or存在提供与 perl 相同的功能,例如

process_without_error or die

我认为没有xor命名函数的原因可能是在这种情况下低优先级运算符没有意义,而且它已经是一个足够令人困惑的情况了!

于 2009-02-25T12:11:39.990 回答
12

尝试^

true  ^ false #=> true
true  ^ true  #=> false
false ^ false #=> false

虽然没有简单的英语等效运算符。

于 2009-02-25T08:55:53.923 回答
10

作为 Matt Van Horn 对任意类型使用 XOR 的双重否定技巧的替代方法,您可以链接另一个 XOR 测试,从nil. IE:

!!foo ^ !!bar

相当于

nil ^ foo ^ bar

这在我看来更整洁,我想需要更少的逻辑操作

于 2014-07-15T12:34:02.520 回答
2

任何实现xor都不允许短路。无论如何,这两个表达式都需要进行评估。

Ruby 确实提供了^运算符,但这会阻塞真实值。我已经实现了一个函数来处理我想要一个xor更像andand的情况or

def xor(a,b)
  (a and (not b)) or ((not a) and b)
end

与 不同^的是,此函数可用于类似以下情况:

xor("hello".match(/llo/), false) # => true
xor(nil, 1239)                   # => true
xor("cupcake", false)            # => false
于 2012-08-08T13:50:15.380 回答
2

约翰的回答似乎不正确。在 irb 1.9.3 中,xor("cupcake", false) 返回 true,正如您所期望的。

1.9.3-p429 :104 > def xor(a,b)
1.9.3-p429 :105?>     (a and (not b)) or ((not a) and b)
1.9.3-p429 :106?>   end
 => nil 
1.9.3-p429 :107 > xor(false, true)
 => true 
1.9.3-p429 :108 > xor("cupcake", false)
 => true 
于 2013-08-06T04:19:44.297 回答