3等于号或案例相等运算符

22
在Ruby中,Integer === 5返回true。同样地,String === "karthik"也返回true
然而,5 === Integer却返回false"karthik" === String也是如此。
为什么这个运算符不是交换律的呢?
4个回答

38
简单的答案是:因为这没有意义。操作符描述的关系不满足交换律,为什么操作符应该满足呢?
看看你自己的例子:5 是一个 Integer。但是 Integer 是一个 5 吗?这究竟是什么意思? === 是一个子类型包含运算符,子类型包含并不满足交换律。
子类型包含运算符使用等号,通常被称为三个等于号、三重等号或者 case 相等性运算符,这事实上非常不幸,因为它不但与相等性毫无关系,而且也不遵循许多相等性遵循的定律,如传递性和你提到的交换律等。
要了解有关我的关于 === 的 ranting,请参见:
- 在Ruby中,===操作符是什么? - Ruby 中的===== - Integer === 3如何运作?

7

一个非常简单的原因是,对于类的is_a?关系不能是可交换的。考虑两个操作数都是类的情况:

Class === String

这将返回true,因为String.is_a?(Class)。然而,String === Class会返回false,因为Class.is_a?(String)是false,这当然是应该的。
另一个原因是===的语义取决于其左操作数。这有两个原因:a)在ruby中,语义始终取决于左操作数,因为左操作数是方法调用的接收者;b)它很有用,因此您可以在具有预期语义的情况语句中使用类、范围和正则表达式等。

2

许多运算符不是可交换的。

===被称为“情况等式运算符”,因为在分支是情况时调用它。

这很好和有用:

foo = 42
case foo
when Integer
  # branches here
when String
  # etc...
end

如果这样做的话,它并不会很有用。

foo = Integer
case foo
when 42
# would branch here??
when 666
# etc...
end

请注意,在 Ruby 1.9 中,对于 Proc/lambda,=== 运算符将调用该 Proc:
divisible_by_three = ->(x){x % 3 == 0}
divisible_by_three === 42 # => true

case 语句中非常有用,但反过来就不太有用了。


1

需要实现case-when比较

拥有非交换运算符是很正常的。

/ - % [] . -> ^ << >> < <= > >= && || = += -= ,

正如事情所发生的那样,=== 部分存在于 case-when 运算符中。在 Ruby 中,这相当复杂,如果必须简化为可交换操作,则不可能如此。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接