本章主要講述三個(gè)內(nèi)容:
- 什么是條件判斷
- 條件判斷中第比較運(yùn)算符、真假值1、邏輯運(yùn)算符
- 條件判斷的種類及其寫法和使用方法
5.1 什么是條件判斷
條件判斷語句有以下三種:
- if語句
- unless語句
- case語句
5.2 Ruby中的條件
條件與真假值
之前介紹的比較運(yùn)算符可以判斷真假,作為if的條件使用。比較運(yùn)算符的結(jié)果分別為true和false。除了比較運(yùn)算符外,Ruby中還有很多其他可以作為條件判斷的方法。例如,字符串的empty?方法。
p "".empty? #=> true
p "AAA".empty? #=> false
除了true和false外,還有其他值可以作為條件判斷的值。例如,用正則表達(dá)式進(jìn)行匹配時(shí),匹配成功返回該字符串位置,匹配失敗返回nil。
關(guān)于Ruby中的真假值的定義:
真:false,nil以外的所有對(duì)象。
假:false、nil
也就是說,Ruby會(huì)認(rèn)為false與nil代表假,除此以外的所有值都代表真。另外,在 Ruby 中還有個(gè)約定俗成的規(guī)則,為了使程序更 容易理解,返回真假值的方法都要以 ? 結(jié)尾。建議大家在寫程序時(shí)也遵守這個(gè)規(guī)則。
5.3邏輯運(yùn)算符
在判斷多個(gè)條件表達(dá)式時(shí),我們會(huì)用到邏輯運(yùn)算符&&和||.
條件1 && 條件2
表示條件1為真,并且條件2為真,整體的表達(dá)式返回真。兩者同時(shí)為假,則整體的表達(dá)式返回假。
條件1 || 條件2
表示條件1為真,或者條件2 為真時(shí),則整體的表達(dá)式返回真。兩者同時(shí)為假,則整體的表達(dá)式返回假。
!條件
表示相反的條件。
在 Ruby 中,還有與 &&、||、! 意思相同,但優(yōu)先級(jí)略低的邏輯運(yùn)算符 and、or、not。
5.4 if語句
if 條件 then
處理
end
可以省略then
在這基礎(chǔ)上可再加上elsif、else
if 條件1 then
處理1
elsif 條件2 then
處理2
elsif 條件3 then
處理3
else
處理4
end
可以省略then
5.5 unless語句
unless語句的用法剛好與if語句相反。unless語句用法如下:
unless 條件 then
處理
end
可以省略then
unless 語句的形式和 if 語句一樣。但 if 語句是條件為真時(shí)執(zhí)行處理,unless 語句則剛好相反,條件為假時(shí)執(zhí)行處理。 下面是使用 unless 的例子(代碼清單 5.3)。
a = 10
b = 20
unless a > b
p "a 不大于 b"
end
unless語句也可以使用else
unless 條件
處理1
else
處理2
end
這個(gè)與下面的if語句是等價(jià)的。
if 條件
處理2
else
處理1
end
對(duì)比以上兩種寫法,,我們可以知道處理 1 和處理 2 的位置互換了,if語句通過這樣的互換,能達(dá)到與使用 unless 語句時(shí)同樣的效果。
5.6 case語句
case 比較對(duì)象
when 值1 then
處理1
when 值2 then
處理2
when 值3 then
處理3
else
處理4
end
可以省略then
when可以一次指定多個(gè)值。
tags = ["A", "IMG", "PRE"]
tags.each do |tagname|
case tagname
when "P","A","I","B","BLOCKQUOTE"
puts "#{tagname} has child."
when "IMG", "BR"
puts "#{tagname} has no child."
else
puts "#{tagname} cannot be used."
end
end
執(zhí)行示例:
ruby case.rb
A has child.
IMG has no child.
PRE cannot be used.
我們?cè)賮砜纯雌渌印?/p>
array = ["a", 1, nil]
array.each do |item|
case item
when String
puts "item is a String."
when Numeric
puts "item is a Numeric."
else
puts "item is something."
end
end
執(zhí)行示例:
ruby case_class.rb
item is a String.
item is a Numeric.
item is something.
在本例中,程序判斷傳過來的對(duì)象類型是字符串(String 類)還是數(shù)值(Numeric 類),或者均不是以上兩者,然后再輸出相應(yīng)的結(jié)果。 在這里,我們同樣是使用 case 語句,不過判斷的主體與之前的例子有點(diǎn)區(qū)別。
本例中的 when 實(shí)際并不是直接判斷傳過來的字符串,而是先查找該對(duì)象屬于 哪個(gè)類,然后再根據(jù)這個(gè)類的信息來進(jìn)行條件判斷。
我們還可以根據(jù)正則表達(dá)式的匹配結(jié)果進(jìn)行不同處理。下面是使用正則表達(dá)式做判斷的 case 語句的例子。
text.each_line do |line|
case line
when /^From:/i
puts "發(fā)現(xiàn)寄件人信息"
when /^To:/i
puts "發(fā)現(xiàn)收件人信息"
when /^Subject:/i
puts "發(fā)現(xiàn)主題信息"
when /^$/
puts "頭部解析完畢"
exit
else
##跳出處理
end
end
這是一個(gè)解析電子郵件頭部的程序。為了簡(jiǎn)化程序,我們并沒有考慮有多個(gè)頭部的情況,而且電子郵件里的內(nèi)容我們也沒取出來。在這里,大家掌握程序的 大概的處理流程就可以了。
each_line 方法逐行讀取電子郵件正文數(shù)據(jù) text,并將每行的內(nèi)容賦值給變量 line。
這個(gè)是處理文件、文本數(shù)據(jù)時(shí)的典型的寫法。
接著 case 語句判斷得到的字符串的內(nèi)容,執(zhí)行不同的處理。以 From: 開頭時(shí)輸出“發(fā)現(xiàn)寄信人信息”,以 To: 開頭時(shí)輸出“發(fā)現(xiàn)收信人信息”,以 Subject: 開 頭時(shí)輸出“發(fā)現(xiàn)主題信息”。
在正則表達(dá)式中,^ 表示匹配字符串的開始,$ 表示匹配字符串的結(jié)束。——譯者注
=== 與 case
語句 在 case 語句中,when 判斷值是否相等時(shí),實(shí)際是使用 === 運(yùn)算符來判斷的。左邊是數(shù)值或者字符串時(shí),=== 與== 的意義是一樣的,除此以外,=== 還可以與=~ 一樣用來判斷正則表達(dá)式是否匹配,或者判斷右邊的對(duì)象是否屬于左邊的類,等等。對(duì)比單純的判斷兩邊的值是否相等,=== 能表達(dá)更加 廣義的“相等”。
p (/zz/ === "xyzzy") #=> true 判斷正則表達(dá)式是否匹配
p (String === "xyzzy") #=> true 判斷右邊的對(duì)象是否屬于左邊的類
p ((1..3) === 2) #=> true
用 if 語句改寫 case 語句的程序如下所示。請(qǐng)注意 when 指定的對(duì)象在=== 的左邊。

5.7 if修飾符與unless修飾符
if 與 unless可以寫在希望執(zhí)行的代碼后面。
puts "a 比b大" if a > b
這與下面的寫法是等價(jià)的:
if a>b
puts "a比b大 "
end
5.8 總結(jié)
本章介紹了如下內(nèi)容。
- 真假值
真假值是條件表達(dá)式的返回值。- nil或者false時(shí)為假。
- 除此以外的值為真。
- 條件判斷語句
- if語句
- unless語句
- case語句
對(duì)象的同一性
所有的對(duì)象都有標(biāo)識(shí)和值。
標(biāo)識(shí)(ID)用來表示對(duì)象同一性。Ruby 中所有對(duì)象都是唯一的,對(duì)象的 ID 可以通過 object_id(或者 id)方法取得。
ary1 = []
ary2 = []
p ary1.object_id #=> 67653636
p ary2.object_id #=> 67650432
我們用 equal? 方法判斷兩個(gè)對(duì)象是否同一個(gè)對(duì)象(ID 是否相同)。
str1 = "foo"
str2 = str1
str3 = "f" + "o" + "o"
p str1.equal?(str2) #=> true
p str1.equal?(str3) #=> false
對(duì)象的“值”就是對(duì)象擁有的信息。例如,只要對(duì)象的字符串內(nèi)容相等,Ruby 就會(huì)認(rèn)為對(duì)象的值相等。Ruby 使用 == 來判斷對(duì)象的值是否相等。
str1 = "foo"
str2 = "f" + "o" + "o"
p str1 == str2 #=> true
除了 == 以外,Ruby 還提供 eql? 方法用來判斷對(duì)象的值是否相等。== 與 eql? 都是 Object 類定義的方法,大部分情況下它們的執(zhí)行結(jié)果都是一樣 的。但也有例外,數(shù)值類會(huì)重定義 eql? 方法,因此執(zhí)行后有不一樣結(jié)果。
p 1.0 == 1 #=> true
p 1.0.eql?(1) #=> false
憑直覺來講,把 1.0 與 1 判斷為相同的值會(huì)更加方便。在一般情況進(jìn)行值的比較時(shí)使用 ==,但是在一些需要進(jìn)行更嚴(yán)謹(jǐn)?shù)谋容^的程序中,就需要用到 eql? 方法。例如,0 與 0.0 作為散列的鍵時(shí),會(huì)判斷為不同的鍵,這是由于散列對(duì)象內(nèi)部的鍵比較使用了 eql? 方法來判斷。
hash = { 0 => "0"}
p hash[0.0] #=> nil
p hash[0] #=> "0"