等号运算符:==和!=
==运算符,也称为相等或双精度相等,如果两个对象相等,则返回true,否则返回false。
"koan" == "koan" # Output: => true
!=运算符(也称为不等式)与==相反。如果两个对象不相等,则返回true;如果相等,则返回false。
"koan" != "discursive thought" # Output: => true
请注意,具有相同元素但顺序不同的两个数组不相等,同一字母的大写和小写版本也不相等,依此类推。
比较不同类型的数字(例如整数和浮点数)时,如果它们的数值相同,则==将返回true。
2 == 2.0 # Output: => true
等于?
与==运算符测试两个操作数是否相等不同,equal方法检查两个操作数是否引用相同的对象。这是Ruby中最严格的相等形式。
例如:a =“ zen” b =“ zen”
a.object_id # Output: => 20139460
b.object_id # Output :=> 19972120
a.equal? b # Output: => false
在上面的示例中,我们有两个具有相同值的字符串。但是,它们是两个不同的对象,具有不同的对象ID。因此,等于?方法将返回false。
让我们再试一次,仅这次b是对a的引用。注意,两个变量的对象ID相同,因为它们指向同一对象。
a = "zen"
b = a
a.object_id # Output: => 18637360
b.object_id # Output: => 18637360
a.equal? b # Output: => true
eql?
在Hash类中,eql?用于测试密钥是否相等的方法。需要一些背景来解释这一点。在计算的一般上下文中,哈希函数采用任意大小的字符串(或文件),并生成称为哈希码的固定大小的字符串或整数,通常仅称为哈希。一些常用的哈希码类型是MD5,SHA-1和CRC。它们用于加密算法,数据库索引,文件完整性检查等。某些编程语言(例如Ruby)提供一种称为哈希表的集合类型。哈希表是类似于字典的集合,它们成对存储数据,由唯一键及其对应的值组成。在后台,这些密钥存储为哈希码。哈希表通常称为哈希表。请注意,hash一词如何引用哈希码或哈希表。
Ruby提供了一种称为hash的内置方法,用于生成哈希码。在下面的示例中,它接受一个字符串并返回一个哈希码。注意具有相同值的字符串如何始终具有相同的哈希码,即使它们是不同的对象(具有不同的对象ID)也是如此。
"meditation".hash # Output: => 1396080688894079547
"meditation".hash # Output: => 1396080688894079547
"meditation".hash # Output: => 1396080688894079547
hash方法在Object类中包含的Kernel模块中实现,该模块是所有Ruby对象的默认根目录。一些类(例如Symbol和Integer)使用默认实现,而其他类(例如String和Hash)提供其自己的实现。
Symbol.instance_method(:hash).owner # Output: => Kernel
Integer.instance_method(:hash).owner # Output: => Kernel
String.instance_method(:hash).owner # Output: => String
Hash.instance_method(:hash).owner # Output: => Hash
在Ruby中,当我们将某些内容存储在哈希(集合)中时,将作为键提供的对象(例如字符串或符号)转换为哈希码并存储为哈希码。稍后,当从哈希(集合)中检索元素时,我们提供了一个对象作为键,该对象被转换为哈希码并与现有键进行比较。如果存在匹配项,则返回相应项目的值。使用eql进行比较。引擎盖下的方法。
"zen".eql? "zen" # Output: => true
# is the same as
"zen".hash == "zen".hash # Output: => true
在大多数情况下,eql?方法的行为类似于==方法。但是,也有一些例外。例如,eql?比较整数和浮点数时,不执行隐式类型转换。
2 == 2.0 # Output: => true
2.eql? 2.0 # Output: => false
2.hash == 2.0.hash # Output: => false
大小写相等运算符:===
Ruby的许多内置类,例如String,Range和Regexp,提供了自己===运算符的实现,也称为大小写相等,三等号或三等值。因为在每个类中实现的方式不同,所以它的行为取决于调用的对象的类型。通常,如果右侧的对象“属于”左侧的对象或“属于”左侧的对象,则返回true。例如,它可以用来测试一个对象是否是一个类(或其子类之一)的实例。
String === "zen" # Output: => true
Range === (1..2) # Output: => true
Array === [1,2,3] # Output: => true
Integer === 2 # Output: => true
使用其他可能最适合该工作的方法可以实现相同的结果。通常最好编写尽可能易于理解的代码,而又不牺牲效率和简洁性。
2.is_a? Integer # Output: => true
2.kind_of? Integer # Output: => true
2.instance_of? Integer # Output: => false
注意最后一个示例返回false,因为诸如2之类的整数是Fixnum类的实例,而Fixnum类是Integer类的子类。===,is_a?和instance_of?如果对象是给定类或任何子类的实例,则方法返回true。instance_of方法更严格,仅当对象是该确切类的实例而不是子类的实例时才返回true。
is_a?和kind_of?方法在内核模块中实现,该模块由Object类混合。两者都是同一方法的别名。让我们验证一下:
Kernel.instance_method(:kind_of?)== Kernel.instance_method(:is_a?)#输出:=> true
范围实现===
在范围对象上调用===运算符时,如果右侧的值落在左侧的范围内,则它返回true。
(1..4) === 3 # Output: => true
(1..4) === 2.345 # Output: => true
(1..4) === 6 # Output: => false
("a".."d") === "c" # Output: => true
("a".."d") === "e" # Output: => false
请记住,===运算符会调用左侧对象的===方法。因此(1..4)=== 3等于(1..4)。===3。换句话说,左侧操作数的类将定义===方法的哪种实现是调用,因此操作数位置不可互换。
正则表达式的===实现
如果右侧的字符串与左侧的正则表达式匹配,则返回true。/ zen / ===“今天练习zazen”#输出:=> true#与“今天练习zazen”相同== / / zen /
在case / when语句中===运算符的隐式用法
此操作符还用于case / when语句的内部。这是其最常见的用法。
minutes = 15
case minutes
when 10..20
puts "match"
else
puts "no match"
end
# Output: match
在上面的示例中,如果Ruby隐式使用了double equal运算符(==),则范围10..20将不被视为等于诸如15的整数。之所以匹配,是因为Triple equal运算符(===)为在所有case / when语句中隐式使用。上面示例中的代码等效于:
if (10..20) === minutes
puts "match"
else
puts "no match"
end
模式匹配运算符:=〜和!〜
=〜(等号)和!〜(等号)运算符用于将字符串和符号与正则表达式模式进行匹配。
String和Symbol类中==方法的实现期望使用正则表达式(Regexp类的实例)作为参数。
"practice zazen" =~ /zen/ # Output: => 11
"practice zazen" =~ /discursive thought/ # Output: => nil
:zazen =~ /zen/ # Output: => 2
:zazen =~ /discursive thought/ # Output: => nil
Regexp类中的实现期望使用字符串或符号作为参数。
/zen/ =~ "practice zazen" # Output: => 11
/zen/ =~ "discursive thought" # Output: => nil
在所有实现中,当字符串或符号与Regexp模式匹配时,它将返回一个整数,该整数是匹配的位置(索引)。如果不匹配,则返回nil。请记住,在Ruby中,任何整数值都是“ truthy”,而nil是“ falsy”,因此=〜运算符可用于if语句和三元运算符。
puts "yes" if "zazen" =~ /zen/ # Output: => yes
"zazen" =~ /zen/?"yes":"no" # Output: => yes
模式匹配运算符对于编写较短的if语句也很有用。例:
if meditation_type == "zazen" || meditation_type == "shikantaza" || meditation_type == "kinhin"
true
end
Can be rewritten as:
if meditation_type =~ /^(zazen|shikantaza|kinhin)$/
true
end
!〜运算符与=〜相反,当没有匹配项时返回true,在有匹配项时返回false。
有关更多信息,请参见此博客文章。
"a" == "a"
,"a" === "a"
和"a".eql? "a"
。但这是错误的:("a".equal? "a"
我的是红宝石1.9.2-p180)