什么是“一流”物品?


191

在给定的编程语言中,什么时候将对象或其他东西称为“一流”,为什么?它们与没有语言的语言有何不同?

编辑。当一个人说“一切都是对象”时(就像在Python中一样),他的确意味着“一切都是一流的”吗?


1
可以将这个问题迁移到programmers.SE吗?还是在那里不合适?我认为这个问题很好。只是无法说出哪个论坛最适合。
Shashank Sawant 2014年

16
投票决定要重新开放...可悲的是,这似乎确实是由不编程的人关闭的,很明显是在主题上:/
djechlin

Answers:


176

简而言之,这意味着对对象的使用没有任何限制。它与任何其他对象相同。

第一类对象是一个实体,可以动态创建,销毁,传递给函数,将其作为值返回,并具有编程语言中其他变量所具有的所有权利。

根据语言,这可能意味着:

  • 可表示为匿名文字值
  • 可存储在变量中
  • 可存储在数据结构中
  • 具有固有身份(独立于任何给定名称)
  • 在与其他实体平等方面具有可比性
  • 可作为参数传递给过程/功能
  • 由于过程/功能可退还
  • 在运行时可构造
  • 可打印
  • 易读
  • 在分布式过程之间可传播
  • 在外部运行过程中可存储

来源

在C ++函数中,它们本身不是一流的对象,但是:

  • 您可以覆盖'()'运算符,以使它具有对象函数,这是一流的。
  • 函数指针是一流的。
  • boost bind,lambda和function确实提供了一流的功能

在C ++中,类不是一流的对象,但这些类的实例是。在Python中,类对象都是一流的对象。(有关将类作为对象的更多详细信息,请参见此答案)。

这是Javascript一流函数的示例:

// f: function that takes a number and returns a number
// deltaX: small positive number
// returns a function that is an approximate derivative of f
function makeDerivative( f, deltaX )
{
    var deriv = function(x)
    { 
       return ( f(x + deltaX) - f(x) )/ deltaX;
    }
    return deriv;
}
var cos = makeDerivative( Math.sin, 0.000001);
// cos(0)     ~> 1
// cos(pi/2)  ~> 0

来源

不是第一类对象的实体称为第二类对象。C ++中的函数是第二类,因为它们不能动态创建。

关于编辑:

编辑。当一个人说“一切都是对象”时(就像在Python中一样),他的确意味着“一切都是一流的”吗?

对象一词可以宽松地使用,并不意味着是一流的。将整个概念称为“一流实体”可能更有意义。但是在Python中,它们的目标是使所有东西都达到一流。我相信发表你讲话的人的意图是一流的。


2
您能否举一些非“一流”对象的例子?
Sudip Bhandari'7

1
@SudipBhandari我想知道同样的事情,最后偶然发现了有关该主题的有用的Wikipedia文章:一流的公民/对象。我发现Robin Popplestone的定义特别有用。(顺便说一句,发表WP文章似乎很明显,但是我没有意识到这是一个基本的编程语言概念)
mblakesley

19

“当一个人说“一切都是对象”时(就像在Python中一样),他的意思确实是“一切都是一流的”吗?”

是。

Python中的所有内容都是正确的对象。即使是其他语言中的“原始类型”也是如此。

您会发现像这样的对象2实际上具有相当丰富和复杂的界面。

>>> dir(2)
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__str__', '__sub__', '__truediv__', '__xor__']

由于所有内容都是Python中的一流对象,因此很少有晦涩的特殊情况。

例如,在Java中,有一些原始类型(int,bool,double,char)不是适当的对象。这就是Java必须将Integer,Boolean,Double和Character作为一流类型引入的原因。对于初学者来说,这可能很难教-尚不清楚为什么原始类型和类必须同时存在。

这也意味着对象的类本身就是对象。这与C ++不同,C ++中的类在运行时并不总是有明显的存在。

对象的类型2type 'int'对象,它具有方法,属性和类型。

>>> type(2)
<class 'int'>

内置类型的类型inttype 'type'对象。这也具有方法和属性。

>>> type(type(2))
<class 'type'>

1
现代Python确实如此。在旧的Python中(第1版?那是我的时代),您不能从继承int。因此,“旧”类与“新类”(在3中,不再有旧类)。
基思·品森

17

“头等舱”意味着您可以按常规方式对它们进行操作。在大多数情况下,这仅意味着您可以将这些一等公民作为函数的参数传递,或从函数中返回它们。

对于对象而言,这是不言而喻的,但对于功能甚至类而言,并不总是那么明显:

void f(int n) { return n * 2; }

void g(Action<int> a, int n) { return a(n); }

// Now call g and pass f:

g(f, 10); // = 20

这是C#中的一个示例,其中函数实际上不是一流的对象。因此,以上代码使用一个小的解决方法(即称为的通用委托Action<>)将函数作为参数传递。其他语言(例如Ruby)甚至可以将类和代码块视为普通变量(或在Ruby中为常量)。



1

国际海事组织,这是用来用自然语言描述事物的那些隐喻之一。该术语本质上用于将功能描述为第一类对象的上下文中。

如果您考虑使用面向对象的语言,我们可以为对象赋予各种功能,例如:继承,类定义,传递给代码的其他部分的能力(方法参数),存储在数据结构中的能力等。与通常不视为对象的实体相同,就像Java脚本中的函数一样,此类实体被视为第一类对象。

头等舱本质上是指不作为第二等舱(具有降级的行为)处理。本质上,嘲讽是完美的还是无法区分的。

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.