当人们说“一切都是对象”(例如在Python中)时,他们确实意味着“一切都是一等公民”吗?
简而言之,它意味着对象使用没有限制。它与任何其他对象相同。
一等公民是指可以被动态创建、销毁、传递给函数、作为值返回,并具有编程语言中其他变量拥有的所有权利的实体。
根据不同的语言,这可能意味着:
- 可以表达为匿名文字值
- 可存储在变量中
- 可以存储在数据结构中
- 具有固有身份(独立于任何给定名称之外)
- 可与其他实体进行平等比较
- 可作为过程/函数的参数传递
- 可作为过程/函数的结果返回
- 可在运行时构建
- 可打印
- 可读取
- 可在分布式进程间传输
- 可在运行进程之外存储
出处。
在C++中,函数本身不是一等公民对象,但是:
在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中,他们确实力求使一切成为头等的。我相信你所引述的那个人的意图是指头等的实体。
当有人说“一切皆对象”(比如在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中所有东西都是一等对象,所以相对而言没有太多晦涩的特殊情况。>>> type(2)
<class 'int'>
内置类型如int
的类型是type 'type'
对象。它还有方法和属性。
内置类型如int
的类型是type 'type'
对象。它还有方法和属性。
>>> type(type(2))
<class 'type'>
dir(&)
。仍然有语言语法的部分不能赋值给变量,也不能用作一等对象。 - Tristan Bodding-Long“一等公民”指可以按照通常方式对其进行操作。大多数情况下,这只意味着您可以将这些一等公民作为参数传递给函数,或从函数中返回它们。
对于对象来说,这是不言自明的,但对于函数甚至类来说,情况并非总是如此明显:
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的情况下,常量)。
来自 《计算机程序的构造和解释》第二讲A(1986年)中一张幻灯片上的话,该幻灯片引用了Christopher Stracey的话:
一等公民的权利和特权:
我认为这是一种用自然语言描述事物的比喻之一。该术语主要用于描述函数作为一等对象的情境。
如果您考虑面向对象的编程语言,我们可以为对象赋予各种特性,例如:继承、类定义、能够传递到代码的其他部分(方法参数)、能够存储在数据结构中等等。如果我们可以对一个通常不被视为对象的实体进行相同的操作,例如 JavaScript 中的函数,则将这些实体视为一等对象。
这里的“一等”基本上意味着不被当作二等对象(行为降级)。模拟是完美的或无法区分的。
2+2
"foo"+"bar"
2*3
"bla"*3
但是你不能将运算符分配给变量:
operator = +
operators = [+,*]
true
”和“false
”。根据编程语言的不同,你可能会有更多选择(例如,在C语言中使用数组[1,2,3]
,或在Scheme中使用列表'(1 2 3)
)。 - Alex M.