本文介绍 Erlang 语言中使用的各种数据类型以及这些数据类型在 Erlang 虚拟机内部的表示和实现。了解数据类型的实现可以帮助大家在实际开发过程中正确选择数据类型,并且可以更好更高效地操作这些数据类型。本文对 Erlang 数据类型及实现的总结目前是最全面的,可以作为 Erlang 数据结构的参考手册。尽管我写的内容都试图在各种参考资料和 Erlang 虚拟机源代码中验证,但是难免会有理解错误或各种低级错误,希望大家指正,也希望能对 Erlang 爱好者们有帮助。

Erlang数据类型回顾

Erlang 从语言的层面上说是一门比较简单的语言,因此语言原生的数据结构也比较简单。下面简单回顾一下 Erlang 语言支持的数据结构:

  • 整数:小整数和大整数。Erlang 可以表达任意大小的整数,只要不超过内存容量。如果一个整数可以用一个机器字[注1]表示,那么这个整数在内部通过“小整数”表示(这里是粗略的描述,实际不到一个机器字);否则,自动升级为“大整数”表示。在用户层面感知不到内部的具体表示,只要用就行了。示例:1,-1,123,473804731289473815748315139。
  • 浮点数:标准的 IEEE 754-1985 格式的浮点数。例如 3.14,1.234E-10,-0.5。
  • atom(原子):小写字母开头的不带引号的字符串,是一种字面常量,可以用来表达任何想表达的意义。也可以用单引号引起来,这样用起来更灵活,比如第一个字母可以大写,中间还可以插入空格。示例:abc,node@myhost.com,error,ok,'Hello World'。
  • 布尔值:实际上内部就是原子 true 和原子 false 表示的,但是有一些 BIF(例如 is_boolean)和操作符(例如 and 和 or 等)用于支持布尔操作的语义。
  • tuple(元组):组合数据结构,相当于固定大小的数组,每一个元素可以是任意类型。示例: {error, badarg},{person, "Siyao", 1985}。
  • list(列表):看上去和元组一样,也是组合数据结构,每一个元素可以是任意类型,可以包含任意个元素,由于 Erlang 变量都是 immutable 的,所以列表的大小也是不可变的,但是列表的内部表示和支持的操作和元组完全不同。示例:[monday, tuesday],[{person, "Alice"}, {person, "Bob"}]。
  • 字符串:实际上就是字符的列表,而字符实际上和整数没有区别。字符串就是一种采用大家熟知的字符串表示语法表示字符列表的语法糖。示例:"Hello World"。注意字符串用的是双引号,而原子用的是单引号。
  • fun(匿名函数):fun 是体现 Erlang 作为函数式语言的一个重要特性。fun 是“匿名”函数,可以在程序中动态生成,可以当做数据传入其他函数或从函数返回。因此 fun 类型的数据也是 Erlang 中的一种数据结构。示例:fun(X) -> 2*X end。
  • binary:用于表示一堆原始的无类型的字节数据。由于 binary 是整块的数据,所以非常适合各种数据传输和处理的场合。binary 可以方便地和 Erlang 中其他数据结构互相转换,因此相当于可以在语言层面非常方便地执行数据结构的 marshalling 和 unmarshalling 操作。在 binary 中还可以打破字节的边界进行任意位匹配操作,因此可以非常方便地从各种二进制数据(例如网络数据包和二进制文件等)中提取字段。
  • ref:通过 BIF 调用 make_ref() 生成的一个几乎唯一的值,因为在同一 Erlang 节点上,连续调用 \(2^{82}\) 次 make_ref() 得到的值都是不一样的。ref 是透明的数据类型,只能拿来用,但不能对其操作。ref 数据可以放在消息里发送至其他 Erlang 节点,Erlang 的分布式机制会自动加上节点相关的信息,使得 ref 在整个集群内保持几乎唯一。也可以看出,ref 有两种表示形式,一种是 local 表示形式,还有一种是 external 形式。local 版本就是在本地的表示形式,但是发送到其他节点之后,其他节点得到的 ref 数据就是通过 external 形式表示的。
  • pid:Erlang 进程 id。类似 ref,也是透明的,也区分 local 和 external。
  • port:表示 port id,同样也是透明的,并区分 local 和 external。

以上完整地概述了 Erlang 语言中采用的数据类型。下面我们就来看这些数据类型在 Erlang 虚拟机内部都是怎么表达和实现的。了解这些原理性的内容我们就可以更加高效地使用这些数据结构。


[注1] 这里说的机器字(后面都简称“字”)指的是机器原生指针宽度的数据结构。比如在 64 位机器上,机器字长度为 8 个字节。要注意这里所说的机器字和 Intel 文档中的“习俗”不同。Intel 文档中因为历史原因,一直将一个字定义为 16 位,即 2 字节,所以 64 位宽的数据结构在 Intel 的文档中都表示为 quad word(因此在对应的汇编指令中也会添加 q 后缀)。

Erlang数据类型的表示和实现(1)——数据类型回顾的更多相关文章

  1. SSIS 数据类型 第二篇:变量的数据类型

    变量(Variable)用于存储在Package运行时用到的值,集成服务支持两种类型的变量:用户自定义的变量和系统变量,自定义的变量由用户来定义,系统变量由集成服务来定义. 变量的用途十分广泛,用于容 ...

  2. Java基础(34):Java中基本数据类型的包装类(主要为了不同数据类型之间更方便的进行转换)(Wrapper类)

    相信各位小伙伴们对基本数据类型都非常熟悉,例如 int.float.double.boolean.char 等.基本数据类型是不具备对象的特性的,比如基本类型不能调用方法.功能简单...,为了让基本数 ...

  3. ArcGIS API for JavaScript 中的数据类型【vs】GPServer的数据类型

    熟悉GPServer的同学肯定知道,GPServer在10.1的ArcMap后需要执行成功一次才能发布. 发布GPServer,可以是ArcMap的工具箱的工具,也可以是自己写的模型. 不管是ArcM ...

  4. c++ 常用数据类型,命名规则, 不常有数据类型

    1. 常用数据类型 最大值0111111111111111 = 32767最小值1000000000000000 = -32768 short 最低16位 2**7 - 1 负值:反码 int 至少和 ...

  5. JavaScript的数据类型---最全,最详细的数据类型,高级的工程师从数据类型开始

    一.基本数据类型 1.字符串数据类型     var hello="你好啊";     var hello='你好啊';示例:<script language="j ...

  6. char数据类型,编程能用的最小数据类型.

    关于数据类型, char占1bit,8bites. signed代表有符号,包括正负数,和0; unsigned代表无符号,只包括0和整数; signed和unsigned的主要区别就是它们的最高位是 ...

  7. 建议2:注意Javascript数据类型的特殊性---(3)正确检测数据类型

    使用typeof预算符返回一个用于识别其运算数类型的字符串.对于任何变量来说,使用typeof预算符总是以字符串的形式返回一下6种类型之一 number string boolean object f ...

  8. python基础(9):基本数据类型四(set集合)、基础数据类型补充、深浅拷贝

    1. 基础数据类型补充 li = ["李嘉诚", "麻花藤", "⻩海峰", "刘嘉玲"] s = "_&qu ...

  9. Python之路-变量和基本数据类型详解(变量、数据类型、)

    一.注释 注释的作用: 增加程序的可读性 作为调试用 提高团队的合作效率 注释的分类 1.单行注释 以井号(#)开头,右边的所有内容当做说明 2.多行注释 以三对单引号(’’’注释内容’’’)将注释包 ...

  10. 基本数据类型的值传递 和引用数据类型的引用传递 Day06

    ValueTest1.java package com.sxt.valuetest; /* * 基本数据类型的传递:传递的是值得副本 */ public class ValueTest1 { publ ...

随机推荐

  1. 第三部分 OpenStack镜像管理

    一.简介 很多源都有为OpenStack已经编译好的各种镜像了,您可以直接下载并通过使用这些镜像来熟悉OpenStack. 不过如果是为生产环境进行部署的话,您一定需要构建含有定制软件或配置的镜像文件 ...

  2. leetcode 39. Combination Sum 、40. Combination Sum II 、216. Combination Sum III

    39. Combination Sum 依旧与subsets问题相似,每次选择这个数是否参加到求和中 因为是可以重复的,所以每次递归还是在i上,如果不能重复,就可以变成i+1 class Soluti ...

  3. 论文笔记 Pose-driven Deep Convolutional Model for Person Re-identification_tianqi_2017_ICCV

    1. 摘要 为解决姿态变化的问题,作者提出Pose-driven-deep convolutional model(PDC),结合了global feature跟local feature, 而loc ...

  4. ZCMU 1019: 分金币

    解题思路: 附上刘汝佳老师的解题过程: 首先最终每个人的金币数量可以计算出来,它等于金币总数除以人数n.接下来用M来表示每个人最终拥有的金币数. 现在假设编号为 i 的人初始有Ai 枚金币,对于1号来 ...

  5. 【vue知识点】2)vue登录认证

    要点: 客户端登录要唯一 ——> token除了客户端要验证外,服务器端也要校验  (处理:token应该包含用户的基本信息,这样服务端解密token的时候就知道是哪个账户) (如果只是使用to ...

  6. MapReduce操作Hbase --table2file

    官方手册:http://hbase.apache.org/book.html#mapreduce.example 简单的操作,将hbase表中的数据写入到文件中. RunJob 源码: import ...

  7. echarts显示X轴最后一个lable

    代码: xAxis: [ { axisLabel: { showMaxLabel: true } } ]

  8. JMeter入门教程

    转自 http://blog.csdn.net/w565911788/article/details/7629787 1.Jmeter 概要描叙 jmeter 是一款专门用于功能测试和压力测试的轻量级 ...

  9. Gitlab+Jenkins学习之路(十)之Jenkins按角色授权和Pipeline

    一.Jenkins按角色授权 当一个公司的开发分为多个组别,或者是多个项目等等.用于公司内部测试,让开发人员自行构建测试,此时不可能让所有的开发都在公用一个构建,这样变得很混乱,为了解决这一问题,je ...

  10. deque!

    deque:双端队列 比较常用的函数: que.back() 返回容器que的最后一个元素的引用.如果que为空,则该操作未定义. que.begin() 传回迭代器中的第一个数据地址. que.cl ...