【问题标题】:Determining type of an object in ruby确定Ruby中对象的类型
【发布时间】:2013-03-24 01:54:37
【问题描述】:

我将使用 python 作为我正在寻找的示例(如果您不了解 Python,可以将其视为伪代码):

>>> a = 1
>>> type(a)
<type 'int'>

我知道在 ruby​​ 中我可以做到:

1.9.3p194 :002 > 1.class
 => Fixnum 

但是这是确定对象类型的正确方法吗?

【问题讨论】:

  • @JörgWMittag 然而 AFAICR 这就是 `type` 在 Python 中所做的,尽管我的记忆很模糊。您需要isinstance 或检查回复。但只是说“不!!!”现在真的没有帮助,是吗?而是考虑具有教育意义。
  • @JörgWMittag 虽然我很同情,但 OP 提供了在 Ruby 中模仿的代码。除非您真的教育 OP 说不,IMO 没有帮助。即使你这样做了,它也可能只是信息性的,因为 OP 通过代码定义了他/她想要什么。
  • @JörgWMittag - 在 Ruby 中,一切都是对象,因此没有 Python 中的原始类型(int、long、boolean 等)。因此,在 Ruby 中,类是类型定义。这也不限于 Ruby,类和类型这两个词在其他几种语言中是同义词,在 OOP 理论中更广泛。
  • 既然我们在这里真正谈论的是 Ruby,类型和类是同义词,对此没有争议,所有值都是对象。所以对于任何简单谈论 Ruby 的人来说,类 类型。 - 参考:ruby-lang.org/en/about
  • @JörgWMittag 到目前为止,这篇文章内容丰富,有机会我会阅读其余部分。特别是,库克似乎很好地表达了(并且比我拥有更多的背景知识)为什么声称(正如我的一位教授所做的那样)Python、Ruby 和其他动态类型语言“不是 真的面向对象”(他可能的意思是,没有意识到,它们不是面向 ADT 的)。但是 Ruby 不是静态类型的,因此它没有库克所描述的 ADT,因此您基于这种区别的反对意见没有帮助。

标签: ruby types


【解决方案1】:

确定对象“类型”的正确方法是调用object.class

由于类可以从其他类继承,如果您想确定一个对象是否“属于特定类型”,您可以调用object.is_a?(ClassName) 来查看object 是属于ClassName 类型还是派生自它。

在 Ruby 中通常不进行类型检查,而是根据对象响应特定方法的能力来评估对象,通常称为“Duck typing”。换句话说,如果它响应您想要的方法,则没有理由对类型进行特殊处理。

例如,object.is_a?(String) 过于严格,因为另一个类可能会实现将其转换为字符串的方法,或者使其行为与 String 的行为方式相同。 object.respond_to?(:to_s) 将是一种更好的方法来测试有问题的对象是否符合您的要求。

【讨论】:

  • -1。 #class 确实返回对象的类型,它返回它的。这个名字应该是一个死的赠品。 Class 和 Type 在 OO 中是两个完全不同的概念。
  • @Jörg W Mittag:我不同意。 “类”和“处理器速度”(举个例子)是两个完全不同的概念,但“类”和“类型”是密切相关的概念。例如,the Wikipedia article on Class 是这样说的:“在面向对象编程中,类是用于定义不同类型的构造。” tadman 对提问者很有帮助。
  • @JörgWMittag 在 Ruby 中,与 C、JavaScript 和其他语言中的 typeof 最接近的是 class。 Ruby 中没有像其他语言那样的正式协议系统,Objective-C 是与之最接近的 Smalltalk。如果您将“类型”定义为“以可接受的结果响应特定方法集的对象”,那么实际上没有办法断言。它太松了。大多数情况下,在 Ruby 中,当引用对象的类型时,可以理解为您在谈论类。出于这个原因,我确实在引号中使用了术语类型。
  • @Jörg W Mittag:我继续断言“类”和“类型”在 OO 中肯定不是完全不同的概念,正如引用所证明的那样。 (另外:你如何在 Java 中声明一个变量?通过给 either 变量的 typeclass 加上它的名字: "int i" 或 "Integer j".) tadman 以一种似乎让提问者和普通观众都满意的方式回答了这个问题,同时澄清了 Ruby 使用的术语。我没有兴趣在面向对象术语的细节问题上进行学术讨论,所以请说出最后的话。
  • @TeemuLeisti 这里的大部分问题都来自这样一个事实:Ruby 中的 everything 都是一个对象,因此也有一个类,而几乎所有其他语言中都有原始的 types 不是对象并且没有类,与对象相反。当没有纯类型这样的东西,也没有办法正式定义它时,在 Ruby 世界中,它的含义变得特别模糊。除了他自己的思想之外,Matz 并没有严格遵守任何特定的思想流派。
【解决方案2】:

你也可以试试:instance_of?

p 1.instance_of? Fixnum    #=> True
p "1".instance_of? String  #=> True
p [1,2].instance_of? Array #=> True

【讨论】:

    【解决方案3】:

    在 Ruby 中,您实际上并不关心对象的类本身是什么,您只关心它是否响应特定的方法。这被称为Duck Typing,您会在各种 Ruby 代码库中看到它。

    所以在很多(如果不是大多数)情况下,最好使用 Duck Typing 使用 #respond_to?(method)

    object.respond_to?(:to_i)
    

    【讨论】:

    • 有效点。没有回答问题,但符合问题的精神。
    • @user566245 很好,它响应_to?(:the_question),但就像你说的它不回答问题,只是提供相关信息。很确定答案需要回答问题。
    【解决方案4】:

    我会说“是”。 正如“马茨”在他的一次演讲中所说的那样, “Ruby 对象没有类型。” 不是全部,而是他试图传达给我们的部分。 为什么会有人说 那么“一切都是对象”吗? 为了补充,他说“数据有类型而不是对象”。

    所以我们可能会喜欢这个。

    https://www.youtube.com/watch?v=1l3U1X3z0CE

    但是 Ruby 并不太关心对象的类型,只关心类。 我们使用类而不是类型。然后所有数据都有一个类。

    12345.class
    
    'my string'.class
    

    他们也可能有祖先

    Object.ancestors
    

    他们也有元类,但我会为你保存详细信息。

    一旦您了解了该类,您就可以查找可以使用哪些方法。这就是需要“数据类型”的地方。 如果您真的想了解详细信息,请查看...

    “Ruby 对象模型”

    这是用于 Ruby 如何处理对象的术语。这都是内部的,所以你并没有真正看到很多,但很高兴知道。但这是另一个话题。

    是的!类是数据类型。对象有类,数据有类型。因此,如果您了解数据库,那么您就知道只有有限的类型集。

    文本块 数字

    【讨论】:

    • 例如Object.ancestors # =&gt; [Object, Kernel, BasicObject]
    【解决方案5】:

    变量名.class

    这里的变量名是“a” a.class

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-06
      • 2011-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多