Ruby类类型和case语句

时间:2010-10-11 17:07:38

标签: ruby duck-typing case-statement

之间有什么区别
case item.class
when MyClass
  # do something here
when Array
  # do something different here
when String
  # do a third thing
end

case item.class
when MyClass.class
  # do something here
when Array.class
  # do something different here
when String.class
  # do a third thing
end

出于某种原因,这些中的第一个有时会起作用而第二个起作用,而其他时候,第二个起作用而第一个起作用。为什么?哪一个是“正确”的方式呢?

5 个答案:

答案 0 :(得分:204)

您必须使用:

case item
when MyClass
...

我有同样的问题: How to catch Errno::ECONNRESET class in "case when"?

答案 1 :(得分:52)

是的,Nakilon是正确的,您必须知道threequal ===运算符如何处理when子句中给出的对象。在Ruby中

case item
when MyClass
...
when Array
...
when String
...

真的是

if MyClass === item
...
elsif Array === item
...
elsif String === item
...

理解这种情况是调用一个三等方法(例如MyClass.===(item)),并且可以定义该方法做任何你想做的事情,然后你可以使用带有precisionw的case语句

答案 2 :(得分:9)

您可以使用:

case item.class.to_s
    when 'MyClass'

......当无法进行以下扭曲时:

case item
    when MyClass

原因是case使用===the relationship the === operator describes is not commutative。例如,5Integer,但Integer5?这就是您应该如何看待case / when

答案 3 :(得分:4)

在Ruby中,类名是一个常量,它引用描述特定类的Class类型的对象。这意味着在Ruby中说MyClass等同于在Java中说MyClass.class

obj.classClass类型的对象,用于描述obj的类。如果obj.classMyClass,则使用obj创建MyClass.new(粗略地说)。 MyClassClass类型的对象,它描述使用MyClass.new创建的任何对象。

MyClass.classMyClass对象的类(它是Class类型对象的,它描述了使用{{1}创建的任何对象})。换句话说,MyClass.new

答案 4 :(得分:1)

这取决于item变量的性质。如果它是对象的实例,例如

t = 5

然后

t.class == Fixnum

但如果它本身就是一个类,例如

t = Array

然后它将是Class对象,所以

t.class == Class

编辑:请参阅Nakilon所说的How to catch Errno::ECONNRESET class in "case when"?,因为我的答案可能有误。