Menu Close

一等公民

头等对象(英语:First-class object),在计算机科学中,指称支持其他实体通常能获得的所有运算的实体。这些运算典型的包括:在执行期创造,作为参数传递给其他函数,或存入一个变量等。将一个实体变为头等对象的过程叫做“实化”(Reification)。

“头等对象”这一名称最早由克里斯托弗·斯特雷奇在1960年代发明,原称“头等公民”(First-class citizen),意指函数可作为电脑语言中的头等公民。英文中也称“First-class entity”或“First-class value”。 我们习惯称其为一等公民.

一等公民
一等公民

一等公民(First-Class Citizen)是指在一个编程语言中,具有与其他数据类型相同地位和功能的数据类型。例如, 在JavaScript中,函数可以作为变量赋值、作为参数传递、作为返回值返回,以及可以作为对象的属性等。

历史

头等对象和二等对象的概念,在1960年由克里斯托弗·斯特雷奇引入。 实际上他并没有给出严格的术语定义,而是给出了ALGOL语言中实数和过程的对比:

头等对象和二等对象。在Algol程序语言中,一个“实数”可能会出现在一个表达式中或被赋给一个变量,并可能在过程调用中作为实际参数出现。而“过程”只可能会出现在另一个过程调用中,最常见的是作为操作符,有时候也作为实参。除此之外,没有表达式会涉及到过程,或者将过程作为计算结果。因此在某种意义上,在Algol程序语言中的过程是二等公民,它们总是会单独出现,不可能被一个表达式或一个变量表示(形式参数除外)…

在1990年代,拉斐尔·芬克尔提出了二等值和三等值的定义,但这些定义尚未被广泛采用。

定义

一等公民不一定是面向对象程序设计所指的物件,而可以指任何程序中的实体。Robin Popplestone给出如下定义:

  1. 所有项目都有特定的基本权力。
  2. 所有项目都可以作为函数的实际参数。
  3. 所有项目都可以作为函数的结果返回。
  4. 所有项目都可以是赋值语句的主体。
  5. 所有项目都可以等式测试。

一个实体在某语言中被称为“一等公民”,通常具备以下能力:

  1. 可以赋值给变量(Assignable to a variable)
    例如:x = f

  2. 可以作为参数传递给函数(Passable as an argument)
    例如:map(f, list)

  3. 可以作为函数的返回值(Returnable from a function)
    例如:return f

  4. 可以存储在数据结构中(Storable in data structures)
    例如:[f1, f2, f3]

举例说明:以“函数”作为考察对象

语言 函数是否是一等公民 说明
Python ✅ 是 函数可以赋值、传参、返回、存储
JavaScript ✅ 是 函数是对象,具备全部一等公民特性
Java(旧版本) ❌ 否 函数不能直接作为变量、参数、返回值(直到 Java 8 引入 Lambda 表达式)
C ❌ 否 虽然有函数指针,但缺乏真正意义上的封装和组合功能
Haskell ✅ 是 典型的函数式编程语言,函数自然是一等公民

除了函数,还有其他例子:

  • 闭包(Closures)
  • 类与对象
  • 协程(Coroutines)
  • 模块(Modules)

取决于语言是否允许它们满足“一等公民”的定义条件。

范例

最简单的标量数据类型,比如整数和浮点数,几乎总是头等的。在很多较早的语言中,数组和字符串不是头等的:它们不能被作为赋值的对象,或作为形式参数传递给子例程。例如,FORTRAN IV和C都不支持数组赋值,并且它们在作为形式参数传递的时候,实际上只有它们的第一个元素的位置被传递了,它们的大小失去了。C看起来支持数组指针的复制,但实际上它们只是到数组的第一个元素的指针,仍然不承载这个数组的大小。

不同语言中对函数的区别很大,例如C语言与C++中的函数不是头等对象,因为在这些语言中函数不能在执行期创造,而必须在设计时全部写好。相比之下,Scheme中的函数是头等对象,因为可以用lambda表达式来创造匿名函数并作为头等对象来操作。

概念 描述 语言
头等函数 闭包和匿名函数 Dart, Scheme, ML, Haskell, F#, Kotlin, Scala, Swift, Perl, PHP, Python, Raku, JavaScript, Delphi, Rust
头等控制 续体 Scheme, ML, F#
头等类型 依赖类型 Coq, Idris, Agda
头等数据类型 Generic Haskell, C++11
头等多态 非直谓多态
头等消息 动态消息(方法调用) Smalltalk[9], Objective-C[9], Common Lisp
头等类 元类 Smalltalk, Objective-C, Ruby, Python, Delphi, Common Lisp
头等证明 证明对象[10] Coq, Agda

总结:

“一等公民”是指语言中可以像普通数据一样自由传递、赋值、返回、嵌入的数据或结构。

适合用于具有高度抽象能力、支持函数式编程的语言,如:

  • Python
  • JavaScript
  • Scheme
  • Lisp
  • Haskell
  • Scala
  • Ruby

 

 

Entires个相关

除教程外,本网站大部分文章来自互联网,如果有内容冒犯到你,请联系我们删除!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Leave the field below empty!