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

时间:2017-01-07 00:47:28

标签: ruby

Ruby中的所有相等是" strict",类似于PHP中的(process:18319): GLib-CRITICAL **: g_variant_builder_end: assertion 'is_valid_builder (builder)' failed (process:18319): GLib-CRITICAL **: g_variant_get_type: assertion 'value != NULL' failed (process:18319): GLib-CRITICAL **: g_variant_type_is_array: assertion 'g_variant_type_check (type)' failed (process:18319): GLib-CRITICAL **: g_variant_get_type_string: assertion 'value != NULL' failed (process:18319): GLib-ERROR **: g_variant_new: expected array GVariantBuilder but the built value has type '(null)' Trace/breakpoint trap (core dumped) ?我注意到Ruby中有一个===运算符,但它做了不同的事情。

4 个答案:

答案 0 :(得分: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?

答案 1 :(得分: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语句比较事物的默认方法。

答案 2 :(得分:1)

啊......在深入挖掘之后,我想我回答了自己的问题。 Ruby有.eql? .equal? link

答案 3 :(得分: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 === bb === a不同。