if和case之间的区别 - ruby

时间:2016-12-05 17:13:03

标签: ruby

此代码

if response != Net::HTTPNoContent
   raise Exception
end
puts "OK"

打印一个异常,而这段代码

case response
when Net::HTTPNoContent
   puts "OK"
else
   raise Exception
end

向控制台输出“OK”。我想知道发生了什么。 如果您需要更多详细信息,请与我们联系。

2 个答案:

答案 0 :(得分:2)

我认为您的response变量是使用net/http返回的响应对象。该对象的类型将为Net::HTTPNoContent

在您的第一个if变体中,您正在检查您的响应对象是否等于Net::HTTPNoContent 。它不会是。发送请求时,net/http库不会返回类,它将返回一个对象,其中包含有关您的请求响应的所有信息(并且类型为Net::HTTPNoContent,或者某些其他类取决于请求的结果)。

然而,在case变体中,事情的工作方式略有不同。 Ruby试图通过您为每个when分支提供的谓词来了解它的功能。它将执行三等号(===)(如#is_a?,在此示例中,尽管它执行其他操作)与每个分支进行比较,如果有问题的对象是(或来自分支中指定的类(或者,当然,如果对象 确实相等)。

(在Ruby中,类也是对象,这就是为什么你可以将response与类本身进行比较,就像你的if版本一样,它仍然对解释器有意义。)

所以最好通过重写if版本来解释:

if !response.is_a?(Net::HTTPNoContent)
  raise Exception
end

puts "OK"

答案 1 :(得分:0)

简单示例:

a = 'a'
if a != String
   p '-'
else
   p '+'
end

case a
when String
   p '+'
else
   p '-'
end

返回:

#=> -
#=> +

这意味着在第一个示例中,您尝试检查某些响应的值是否等于class。当您使用case when String时,它会检查if a.is_a? String