什么是“第一类”对象?
- 2024-12-27 08:46:00
- admin 原创
- 150
问题描述:
在给定的编程语言中,什么时候对象或其他东西被称为“一流”?为什么?它们与不是一流语言的语言有何不同?
当人们说“一切都是对象”(比如在 Python 中)时,他们的意思确实是“一切都是一流的”吗?
解决方案 1:
简单来说,就是对物品的使用没有任何限制,跟其他物品一样。
第一类对象是可以动态创建、销毁、传递给函数、作为值返回并拥有编程语言中其他变量所具有的所有权利的实体。
根据语言的不同,这可能意味着:
可以表达为匿名文字值
可存储在变量中
可存储在数据结构中
具有内在身份(独立于任何给定的名称)
与其他实体平等比较
可以作为参数传递给过程/函数
可以作为过程/函数的结果返回
运行时可构造
可打印
可读性
可在分布式进程间传输
可存储在正在运行的进程之外
来源。
然而,在 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:
“当一个人说‘一切都是对象’(比如在 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++ 中,类在运行时并不总是具有独特的存在性。
的类型2
是type 'int'
对象,它具有方法、属性和类型。
>>> type(2)
<class 'int'>
内置类型的类型int
是type 'type'
对象。它也有方法和属性。
>>> type(type(2))
<class 'type'>
解决方案 3:
“一等公民” 意味着你可以用通常的方式对它们进行操作。大多数情况下,这只是意味着你可以将这些一等公民作为参数传递给函数,或者从函数中返回它们。
对于对象来说,这是不言而喻的,但对于函数甚至类来说,并不总是那么明显:
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 或 Python)允许将类和代码块视为普通变量(或者在 Ruby 的情况下为常量)。
解决方案 4:
摘自《计算机程序的结构和解释》讲座 2A(1986)中的一张幻灯片,其中引用了Christopher Stracey 的话:
一等公民的权利和特权:
以变量来命名。
作为参数传递给过程。
作为程序的值返回。
纳入数据结构
解决方案 5:
一个简单的理解方法是问:什么不是“一流的”?
在 Python 中,例如+
或之类的运算符*
不是一流的。
您可以直接使用运算符:
2+2
"foo"+"bar"
2*3
"bla"*3
但是你不能将运算符分配给变量:
operator = +
operators = [+,*]
这也意味着:您不能将运算符作为函数参数传递,因为......
... 操作员不是一流的。
解决方案 6:
在我看来,这是自然语言中用来描述事物的隐喻之一。该术语主要用于将函数描述为第一类对象。
如果您考虑面向对象语言,我们可以为对象赋予各种特性,例如:继承、类定义、传递给其他代码部分的能力(方法参数)、存储在数据结构中的能力等。如果我们可以对通常不被视为对象的实体执行相同操作,例如 Java 脚本中的函数,则此类实体被视为第一类对象。
此处的“一等”本质上意味着不作为二等处理(行为退化)。本质上,模拟是完美的或难以区分的。
扫码咨询,免费领取项目管理大礼包!