第5章 条件判断

本章主要讲述三个内容:

  • 什么是条件判断
  • 条件判断中第比较运算符、真假值1、逻辑运算符
  • 条件判断的种类及其写法和使用方法

5.1 什么是条件判断

条件判断语句有以下三种:

  • if语句
  • unless语句
  • case语句

5.2 Ruby中的条件

条件与真假值
之前介绍的比较运算符可以判断真假,作为if的条件使用。比较运算符的结果分别为true和false。除了比较运算符外,Ruby中还有很多其他可以作为条件判断的方法。例如,字符串的empty?方法。

p "".empty? #=> true 
p "AAA".empty? #=> false

除了true和false外,还有其他值可以作为条件判断的值。例如,用正则表达式进行匹配时,匹配成功返回该字符串位置,匹配失败返回nil。
关于Ruby中的真假值的定义:
真:false,nil以外的所有对象。
假:false、nil
也就是说,Ruby会认为false与nil代表假,除此以外的所有值都代表真。另外,在 Ruby 中还有个约定俗成的规则,为了使程序更 容易理解,返回真假值的方法都要以 ? 结尾。建议大家在写程序时也遵守这个规则。

5.3逻辑运算符

在判断多个条件表达式时,我们会用到逻辑运算符&&和||.

条件1 && 条件2
表示条件1为真,并且条件2为真,整体的表达式返回真。两者同时为假,则整体的表达式返回假。

条件1 || 条件2
表示条件1为真,或者条件2 为真时,则整体的表达式返回真。两者同时为假,则整体的表达式返回假。

!条件
表示相反的条件。

在 Ruby 中,还有与 &&、||、! 意思相同,但优先级略低的逻辑运算符 and、or、not。

5.4 if语句

if 条件 then
    处理
end

可以省略then
在这基础上可再加上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 语句是条件为真时执行处理,unless 语句则刚好相反,条件为假时执行处理。 下面是使用 unless 的例子(代码清单 5.3)。

a = 10
b = 20
unless a > b
    p "a 不大于 b" 
end

unless语句也可以使用else

unless 条件
    处理1
else
    处理2
end

这个与下面的if语句是等价的。

if 条件
    处理2
else
    处理1
end

对比以上两种写法,,我们可以知道处理 1 和处理 2 的位置互换了,if语句通过这样的互换,能达到与使用 unless 语句时同样的效果。

5.6 case语句

case 比较对象
when 值1 then
    处理1
when 值2 then
    处理2
when  值3 then
    处理3
else 
    处理4
end

可以省略then

when可以一次指定多个值。

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

执行示例:

ruby case.rb
A has child.
IMG has no child.
PRE cannot be used.

我们再来看看其他例子。

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

执行示例:

ruby case_class.rb
item is a String.
item is a Numeric.
item is something.

在本例中,程序判断传过来的对象类型是字符串(String 类)还是数值(Numeric 类),或者均不是以上两者,然后再输出相应的结果。 在这里,我们同样是使用 case 语句,不过判断的主体与之前的例子有点区别。
本例中的 when 实际并不是直接判断传过来的字符串,而是先查找该对象属于 哪个类,然后再根据这个类的信息来进行条件判断。

我们还可以根据正则表达式的匹配结果进行不同处理。下面是使用正则表达式做判断的 case 语句的例子。

text.each_line do |line|
    case line
    when /^From:/i
        puts "发现寄件人信息"
    when /^To:/i
        puts "发现收件人信息"
    when /^Subject:/i
        puts "发现主题信息"
    when /^$/
        puts "头部解析完毕"
        exit
    else
        ##跳出处理
    end
end

这是一个解析电子邮件头部的程序。为了简化程序,我们并没有考虑有多个头部的情况,而且电子邮件里的内容我们也没取出来。在这里,大家掌握程序的 大概的处理流程就可以了。
each_line 方法逐行读取电子邮件正文数据 text,并将每行的内容赋值给变量 line。
这个是处理文件、文本数据时的典型的写法。
接着 case 语句判断得到的字符串的内容,执行不同的处理。以 From: 开头时输出“发现寄信人信息”,以 To: 开头时输出“发现收信人信息”,以 Subject: 开 头时输出“发现主题信息”。
在正则表达式中,^ 表示匹配字符串的开始,$ 表示匹配字符串的结束。——译者注

=== 与 case

语句 在 case 语句中,when 判断值是否相等时,实际是使用 === 运算符来判断的。左边是数值或者字符串时,=== 与== 的意义是一样的,除此以外,=== 还可以与=~ 一样用来判断正则表达式是否匹配,或者判断右边的对象是否属于左边的类,等等。对比单纯的判断两边的值是否相等,=== 能表达更加 广义的“相等”。

p (/zz/ === "xyzzy") #=> true 判断正则表达式是否匹配
p (String === "xyzzy") #=> true 判断右边的对象是否属于左边的类
p ((1..3) === 2) #=> true

用 if 语句改写 case 语句的程序如下所示。请注意 when 指定的对象在=== 的左边。


截屏2021-01-29 下午2.05.38.png

5.7 if修饰符与unless修饰符

if 与 unless可以写在希望执行的代码后面。

puts "a 比b大" if a > b

这与下面的写法是等价的:

if a>b
    puts "a比b大 "
end 

5.8 总结

本章介绍了如下内容。

  • 真假值
    真假值是条件表达式的返回值。
    • nil或者false时为假。
    • 除此以外的值为真。
  • 条件判断语句
    • if语句
    • unless语句
    • case语句

对象的同一性

所有的对象都有标识和值。
标识(ID)用来表示对象同一性。Ruby 中所有对象都是唯一的,对象的 ID 可以通过 object_id(或者 id)方法取得。

ary1 = [] 
ary2 = [] 
p ary1.object_id #=> 67653636 
p ary2.object_id #=> 67650432

我们用 equal? 方法判断两个对象是否同一个对象(ID 是否相同)。

str1 = "foo" 
str2 = str1 
str3 = "f" + "o" + "o" 
p str1.equal?(str2) #=> true 
p str1.equal?(str3) #=> false

对象的“值”就是对象拥有的信息。例如,只要对象的字符串内容相等,Ruby 就会认为对象的值相等。Ruby 使用 == 来判断对象的值是否相等。

str1 = "foo" 
str2 = "f" + "o" + "o" 
p str1 == str2 #=> true

除了 == 以外,Ruby 还提供 eql? 方法用来判断对象的值是否相等。== 与 eql? 都是 Object 类定义的方法,大部分情况下它们的执行结果都是一样 的。但也有例外,数值类会重定义 eql? 方法,因此执行后有不一样结果。

p 1.0 == 1 #=> true 
p 1.0.eql?(1) #=> false

凭直觉来讲,把 1.0 与 1 判断为相同的值会更加方便。在一般情况进行值的比较时使用 ==,但是在一些需要进行更严谨的比较的程序中,就需要用到 eql? 方法。例如,0 与 0.0 作为散列的键时,会判断为不同的键,这是由于散列对象内部的键比较使用了 eql? 方法来判断。

hash = { 0 => "0"} 
p hash[0.0] #=> nil 
p hash[0] #=> "0"

你可能感兴趣的:(第5章 条件判断)