确定红宝石中物体的类型


364

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

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

我知道我可以做红宝石:

1.9.3p194 :002 > 1.class
 => Fixnum 

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


5
@JörgWMittag尽管我的记忆模糊,但是AFAICR就是`type`在Python中所做的。您需要isinstance 或检查响应。但是简单地说“不!!!” 现在不是真的有用吗?而是考虑接受教育。
戴夫·牛顿

4
@JörgWMittag我很同情,OP提供了在Ruby中模仿的代码。除非您真正教育 OP,说否定是没有帮助的,否则IMO。而且即使您这样做,也可能仅是信息性的,因为OP定义了他/她想要的代码。
戴夫·牛顿

5
@JörgWMittag-在Ruby中,所有东西都是对象,因此没有Python中的原始类型(int,long,boolean等)。因此,在Ruby中,类是类型定义。这也不限于Ruby,单词class和type在其他几种语言中是同义词,在OOP理论中更广泛。
ocodo 2014年

6
由于我们在这里实际上是在谈论Ruby,所以类型和类是同义词,因此对此没有争议,所有值都是对象。因此,对于任何只谈论Ruby的人来说,类就是类型。-参考:ruby-lang.org/en/about
ocodo

2
@JörgWMittag到目前为止,该文章内容丰富,如果有机会,我将继续阅读其余内容。特别是,库克似乎表达得很好(并且比我拥有更多的背景知识),为什么声称(如我的一位教授所做的那样)Python,Ruby和其他动态类型的语言“并没有真正反对”是不正确的”(他可能没有意识到就意味着它们不是面向ADT的)。但是Ruby不是静态类型的,因此它没有Cook所描述的ADT,因此基于这种区别的异议无济于事。
凯尔·斯特兰德

Answers:


607

确定对象“类型”的正确方法是调用,这在Ruby世界中是一个摇摆不定的术语object.class

由于类可以从其他类继承,因此,如果要确定某个对象是否属于“特定类型”,则可以调用该对象object.is_a?(ClassName)以查看object其类型ClassName或从其派生。

通常,在Ruby中不会进行类型检查,而是根据对象对特定方法的响应能力(通常称为“ 鸭子类型 ”)进行评估。换句话说,如果它响应所需的方法,则没有理由对类型进行特别说明。

例如,object.is_a?(String)由于另一个类可能实现将其转换为字符串或使其行为与String行为相同的方法,因此过于僵化。object.respond_to?(:to_s)更好的方法来测试有关对象是否满足您的要求。


13
-1。#class没有返回对象的类型,它返回它的。这个名字应该是个死胡同。类和类型是OO 中两个完全不同的概念。
约尔格W¯¯米塔格

78
@JörgW Mittag:我不同意。(以示例为例)“类”和“处理器速度”是两个完全不同的概念,但是“类”和“类型”是紧密相关的概念。例如,这是Wikipedia上有关Class的文章所说的:“在面向对象的编程中,类是用于定义不同类型的构造。” 塔德曼对发问者有帮助。
Teemu Leisti

18
@JörgWMittag在Ruby中,最接近typeofC,JavaScript和其他语言的是class。Ruby中没有像其他语言中那样的正式协议系统,Objective-C是与之最接近的Smalltalk。如果您将“类型”定义为“对可以接受可接受结果的特定方法集进行响应的对象”,那么实际上就没有办法断言这一点。太松了 在Ruby中,大多数时候引用对象的类型时,都可以理解您在谈论类。出于这个原因,我确实在引号中使用了术语类型。
tadman 2013年

14
@JörgW Mittag:我继续断言,“类”和“类型”在OO中肯定不是完全不同的概念,如引文所示。(另外:你怎么声明在Java中的变量通过给?无论是类型变量,其次是它的名字:“ int i”或“ Integer j”)。tadman回答的方式,似乎满足这两个提问的问题和一般读者,同时阐明了Ruby使用的术语。我没有兴趣对面向对象术语的精妙之处进行学术上的梳理,所以请紧随其后。
Teemu Leisti

11
@TeemuLeisti这里最麻烦的是,Ruby中的所有东西都是对象,因此都有一个类,而实际上,在每种其他语言中,与对象不同的是,原始类型不是对象,也没有类。当没有诸如纯类型之类的东西,并且无法正式定义一个类型时,其含义在Ruby世界中变得尤为模糊。Matz除了自己的思想之外,并不严格遵守这里的任何特定思想流派。
tadman


44

通常,在Ruby中,实际上您实际上并不关心对象的类是什么,您只关心它对某种方法做出的响应。这就是所谓的Duck Typing,您会在各种Ruby代码库中看到它。

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

object.respond_to?(:to_i)

1
有效点。没有回答问题,但触及了问题的实质。
user566245

@ user566245很好,它的respons_to?(:the_question),但是就像您说的那样,它没有回答问题,只是提供了相关信息。相当肯定的答案需要回答这个问题。
R.Rincón10

17

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

因此,我们可能会喜欢上它。

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

但是Ruby对类的对象并不十分在意。我们使用类而不是类型。然后所有数据都有一个类。

12345.class

'my string'.class

他们可能也有祖先

Object.ancestors

他们也有元类,但我会在上面保存详细信息。

一旦知道了该类,就可以查找可以用于该类的方法。那就是需要“数据类型”的地方。如果您真的想了解细节,请查阅...

“ Ruby对象模型”

这是Ruby处理对象的术语。这些都是内部的,因此您看不到太多,但很高兴知道。但这是另一个话题。

是! 该类是数据类型。对象具有类,数据具有类型。因此,如果您了解数据库,那么您将知道只有有限的一组类型。

文字方块数字


例如,Object.ancestors # => [Object, Kernel, BasicObject]
多里安
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.