文档章节

第一类对象(First-class Object)

Barudisshu
 Barudisshu
发布于 2015/04/14 11:47
字数 1173
阅读 1860
收藏 1
In programming language design, a first-class citizen (also object, entity, or value) in a given programming language is an entity which supports all the operations generally available to other entities. These operations typically include being passed as a parameter, returned from a function, and assigned to a variable.

第一类对象(First-class Object)在1960年由Christopher Strachey发明,原来称之为第一类公民(First-class citizen),意思是指函数可以作为电脑中的第一类公民。英文中也称之为First-class entity或First-class value。

定义

第一类对象不一定是指面向对象程序设计中所指的对象,而是指程序中的所有实体(比如:变量、函数、队列、字典等等)。一般第一类对象具有一下特征:


  1. 可以被存入变量或其他结构
  2. 可以被作为参数传递给其他方法/函数
  3. 可以被作为方法/函数的返回值
  4. 可以在执行期被创建,而无需在设计期全部写出
  5. 有固定身份


“固有身份”是指实体有内部表示,而不是根据名字来识别,比如匿名函数,还可以通过赋值叫任何名字。大部分语言的基本类型的数值(int, float)等都是第一类对象;但是数组不一定,比如C中的数组,作为函数参数时,传递的是第一个元素的地址,同时还丢失了数组长度信息。对于大多数的动态语言,函数/方法都是第一类对象,比如Python,但是Ruby不是,因为不能返回一个方法。第一类函数对函数式编程语言来说是必须的。

范例

在大多数语言中,数值和基础类型都是第一类对象,然而不同语言中对函数的区别很大,例如C语言与C++中的函数不是第一类对象,因为在这些语言中函数不能在执行期创造,而必须在设计时全部写好。相比之下,Scheme中的函数是第一类对象,因为可以用lambda语句来创造匿名函数并作为第一类对象来操作。

举个例子

在诸如Python、Scala等函数式编程语言中,最主要的基础是λ演算(lambda caculus),而λ演算的函数可以接受函数当作输入输出。因此,这类编程语言往往实现了第一类函数(First-class Function),以Scala为例。

Scala,顾名思义“可伸缩的”,为了使λ演算变得简洁,Scala实现了第一类值(First-class Value),即所有函数都是first-class values ,这意味着Scala中的所有函数都是值,因此,函数可以作为值一样进行参数传递或者从函数中返回。
作为返回,结果为2
val inc = (x : Int) => x + 1
inc(1)
作为传递,结果为List(2,3,4)
List(1, 2, 3).map((x: Int) => x + 1)

从以上结果可以看出,函数是在执行期被创建的;函数可以是匿名的;有返回值;能够被存储;函数作为实体满足了第一对象概念的定义。

历史背景

第一类对象和第二类对象的概念,在1960年由Christopher Strachey引入。实际上他没有提出严格的术语定义,而是给出了Algol语言中实数和过程的对比:

第一类对象和第二类对象。在Algol程序语言中,一个“实数”可能会出现在一个表达式中或被赋给一个变量,并可能在过程调用中作为实际参数出现。而“过程”只可能会出现在另一个过程调用中,最常见的是作为操作符,有时候也作为实参。除此之外,没有表达式会涉及到过程,或者将过程作为计算结果。因此在某种意义上,在Algol程序语言中的过程是第二类变量,它们总是会单独出现,不可能被一个表达式或一个变量表示(形式参数除外)…
一些编程语言中允许函数在执行时创建,并将其称为”第一类“(First-class),而函数在C语言中不是第一类对象;相对应的称之为第二类对象(second-class objects),因为从函数角度看这类对象是独立的并且能在各种形式操作。像SmallTalk这种全面向对象语言,函数和方法都是第一类对象,因为操作符(+、-、etc)也是对象,因此操作符也是第一类对象。

© 著作权归作者所有

Barudisshu
粉丝 27
博文 62
码字总数 70723
作品 0
茂名
程序员
私信 提问
Synchronized详解

一、使用零长度的byte[]对象作为锁 class Foo implements Runnable { private byte[] lock = new byte[0]; // 特殊的instance变量 Public void methodA() { synchronized(lock) { //… } } ......

寂寞的神
2016/11/06
5
0
python __set__ __get__ 等解释

如果你和我一样,曾经对method和function以及对它们的各种访问方式包括self参数的隐含传递迷惑不解,建议你耐心的看下去。这里还提到了Python属性查找策略,使你清楚的知道Python处理obj.att...

子夜闻雪
2016/04/06
23
0
python_day6_对象

6.1: 类与对象实例 python是一门面向对象编程语言,其中编程方式分为三种范式: 1、面向过程编程 2、函数式编程 分为两种:数学层次的编程与python函数式编程 3、面向对象编程 对象是由类产...

812374156
2017/12/22
0
0
java领域模型中的失血、贫血、充血、胀血模型

为了补大家的遗憾,在此总结下ROBBIN的领域模型的一些观点和大家的补充,在网站和演讲中,robbin将领域模型初步分为4大类: 1,失血模型 2,贫血模型 3,充血模型 4,胀血模型 那么让我们看看...

萧萧恋
2013/07/15
551
1
【转贴】贫血,充血模型的解释以及一些经验(非常经典)

领域模型分为4大类: 1,失血模型 2,贫血模型 3,充血模型 4,胀血模型 那么让我们看看究竟有这些领域模型的具体内容,以及他们的优缺点: 一、失血模型 失血模型简单来说,就是domain obje...

鉴客
2010/08/11
7.6K
8

没有更多内容

加载失败,请刷新页面

加载更多

哪些情况下适合使用云服务器?

我们一直在说云服务器价格适中,具备弹性扩展机制,适合部署中小规模的网站或应用。那么云服务器到底适用于哪些情况呢?如果您需要经常原始计算能力,那么使用独立服务器就能满足需求,因为他...

云漫网络Ruan
今天
10
0
Java 中的 String 有没有长度限制

转载: https://juejin.im/post/5d53653f5188257315539f9a String是Java中很重要的一个数据类型,除了基本数据类型以外,String是被使用的最广泛的了,但是,关于String,其实还是有很多东西...

低至一折起
今天
25
0
OpenStack 简介和几种安装方式总结

OpenStack :是一个由NASA和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项目。项目目标是提供实施简单、可大规模扩展、丰富、标准统一的云计算管理平台。OpenSta...

小海bug
昨天
11
0
DDD(五)

1、引言 之前学习了解了DDD中实体这一概念,那么接下来需要了解的就是值对象、唯一标识。值对象,值就是数字1、2、3,字符串“1”,“2”,“3”,值时对象的特征,对象是一个事物的具体描述...

MrYuZixian
昨天
9
0
解决Mac下VSCode打开zsh乱码

1.乱码问题 iTerm2终端使用Zsh,并且配置Zsh主题,该主题主题需要安装字体来支持箭头效果,在iTerm2中设置这个字体,但是VSCode里这个箭头还是显示乱码。 iTerm2展示如下: VSCode展示如下: 2...

HelloDeveloper
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部