为什么Ruby没有! ==运算符?

3
在 Ruby 中,所有的等式都是“严格”的,类似于 PHP 中的===运算符吗?我注意到 Ruby 中有一个===运算符,但它的作用不同。

快速搜索确定它是用于 when 子句的,所以如果我要猜的话,他们可能只是没有添加 !== - Rogue
对于那些不熟悉 PHP 的人,请解释一下 !== 运算符会返回什么,以及您所说的“严格”是什么意思,最好通过编辑问题来说明。这是否与对象相同与值相同有关? - Cary Swoveland
4个回答

8

===不是一个相等运算符!

不是。

那它是什么呢?

你可能熟悉Javascript和PHP中的===作为相等运算符,但在Ruby中,它不是一个相等运算符,并且与其他语言有根本不同的语义。

那么===是做什么用的呢?

===是模式匹配运算符!

  • ===匹配正则表达式
  • ===检查范围成员资格
  • ===检查属于类的实例
  • ===调用lambda表达式
  • ===有时会检查相等性,但大多数情况下不会

那么这种疯狂的行为如何说得通呢?

  • Enumerable#grep 在内部使用===
  • case when语句也在内部使用===

这就是为什么你可以在case when语句中使用正则表达式、类、范围甚至lambda表达式的原因。

以下是一些示例:

case value
when /regexp/
  # value matches this regexp
when 4..10
  # value is in range
when MyClass
  # value is an instance of class
when ->(value) { ... }
  # lambda expression returns true
when a, b, c
  # value matches one of a, b, c with `===`
when *array
  # value matches an element in array with `===`
when x
  # values is equal to x unless x is one of the above
end

所有这些示例也适用于 pattern === value,以及 grep 方法。我只能猜测为什么没有 !== 方法,但 Tadman 的直觉似乎很准确,=== 大多是间接通过 case whengrep 使用的,因此可能不需要显式的反向运算符。大多数生产代码的样式指南都禁止使用 === 运算符。如果您正在寻找其他相等运算符,请检查 .eql?.equal?

3

Ruby不需要严格的===类型运算符,因为默认比较器==已经相当严格,不像PHP和其他语言。通常情况下不需要进行任何类型转换,所以进行类型转换的情况很少见:

0 == ""
# => false

0 == "0"
# => false

"" == " "
# => false

0 == nil
# => false

0 == 0.0
# => true

事实上,当你使用===时,你往往会因过于具体或邀请意外行为而引起麻烦。
"" === String
# => false

String === ""
# => true

String === Object
# => false

Object === String
# => false
===的含义由不同类以不同方式定义,通常与"相等性"无关。它只是一种类似于<<的简写形式。Object === String实际上是Object.===(String),这就是为什么它产生与String.===(Object)不同的结果。在这种情况下,它的意思是"等于或派生自..."。
正因为其相对罕见,所以!==实际上没有必要存在。===通常只是间接使用,因为它是通过case语句比较事物的默认方法。

@akuhn 我稍微重写了一下。 - tadman

1

啊...深入了解后,我想我回答了自己的问题。Ruby有.eql?.equal?链接


1
Ruby的相等性不是使用==严格的,至少不像JavaScript中的===那样。Ruby有更严格的相等性方法,例如eql?equal?,但===不是用于严格的相等性。===方法被称为包含运算符。它在case语句中最常被隐式使用。这意味着:
case a 
when b ...
when c ...
else ...
end

等同于

if b === a
...
elsif c === a
...
else
...
end

话虽如此,!== 可能存在,但是它只是留给用户去做 !(a === b)。请注意,=== 不具有交换律,例如 a === b 并不等同于 b === a


除非你确切知道自己在做什么,否则不应使用 ===,原因有很多。 - tadman

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