Ruby类类型和case语句

Dav*_*man 127 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
Run Code Online (Sandbox Code Playgroud)

case item.class
when MyClass.class
  # do something here
when Array.class
  # do something different here
when String.class
  # do a third thing
end
Run Code Online (Sandbox Code Playgroud)

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

Nak*_*lon 218

你必须使用:

case item
when MyClass
...
Run Code Online (Sandbox Code Playgroud)

我遇到了同样的问题: 如何在"case when"中捕获Errno :: ECONNRESET类?

  • 使用ActiveRecord时未提及的警告.类比较的ActiveRecord ===方法使用.is_a ?,这意味着类的子类将在case语句中求值为true.https://github.com/rails/rails/blob/04cda1848cb847c2bdad0bfc12160dc8d5547775/activerecord/lib/active_record/core.rb#L135 (3认同)

Fre*_*red 55

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

case item
when MyClass
...
when Array
...
when String
...
Run Code Online (Sandbox Code Playgroud)

是真的

if MyClass === item
...
elsif Array === item
...
elsif String === item
...
Run Code Online (Sandbox Code Playgroud)

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

  • ===只是一种方法,可以定义为执行类的设计者要做的任何事情.还要记住,a === b确实意味着.=== b,所以如果你转换a和b,你可以得到不同的行为.无法保证===是可交换的.实际上,Array === Array为false,但是Object === Object为true,因此Array重新定义了===的语义. (4认同)

use*_*833 11

您可以使用:

case item.class.to_s
    when 'MyClass'
Run Code Online (Sandbox Code Playgroud)

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

case item
    when MyClass
Run Code Online (Sandbox Code Playgroud)

这样做的原因是case使用===操作员描述的关系不是可交换的===.例如,5是一个Integer,但是Integer一个5?这就是你应该怎么想case/ when.

  • “5 是一个整数,但整数是 5 吗”是一个非常人性化的解释,谢谢。 (2认同)

Ken*_*oom 5

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

obj.classClass描述类别的类型的对象obj。如果obj.classMyClass,则obj使用MyClass.new(大致而言)创建。MyClass是类型的对象,Class它描述使用创建的任何对象MyClass.new

MyClass.class是类的MyClass对象(它的类型的对象的Class描述使用创建的任何对象MyClass.new)。换句话说,MyClass.class == Class