本文介绍 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. lvm xfs 扩容

    lvresize -L 300M /dev/vg1/lv1 #重新设定大小 e2fsck -f /dev/vg1/lv1 #检查磁盘错误 (针对ext4执行) resize2fs /dev/vg1/l ...

  2. 基于swoole的聊天室模型

    client.html: <!doctype html><html><head> <meta charset="utf-8"> &l ...

  3. Java日志框架中真的需要判断log.isDebugEnabled()吗?

    在项目中我们经常可以看到这样的代码: if (logger.isDebugEnabled()) { logger.debug(message); } 简单来说,就是用isDebugEnabled方法判 ...

  4. 数据结构基础(1)--数组C语言实现--动态内存分配

    数据结构基础(1)--数组C语言实现--动态内存分配 基本思想:数组是最常用的数据结构,在内存中连续存储,可以静态初始化(int a[2]={1,2}),可以动态初始化 malloc(). 难点就是数 ...

  5. 用HTML编写阿里云

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...

  6. block本质探寻七之内存管理

    说明: <1>阅读本问,请参照block前述文章加以理解: <2>环境:ARC: <3>变量类型:基本数据类型或者对象类型的auto局部变量: 一.三种情形 //代 ...

  7. ios学习路线—Objective-C(属性修饰符)

    readonly: 此标记说明属性是只读的,默认的标记是读写,如果你指定了只读,在@implementation中只需要一个读取器.或者如果你使用@synthesize关键字,也是有读取器方法被解析. ...

  8. 洛谷P4245 【模板】MTT(任意模数NTT)

    题目背景 模板题,无背景 题目描述 给定 22 个多项式 F(x), G(x)F(x),G(x) ,请求出 F(x) * G(x)F(x)∗G(x) . 系数对 pp 取模,且不保证 pp 可以分解成 ...

  9. 有关ajax

    1.什么是ajax? ajax是前端与后端交互所依赖的一项技术,它相当于一座桥梁,沟通了前端与后端. 2.ajax的优点 可以局部更新网页内容. 3.ajax的本质就是xmlHttpRequest对象 ...

  10. json keyname map

    var obj = { fname:'zhao', lname:'yao', parents:{ father:'zhao' }, children:[ { dname:'zhaoyiyi' } ] ...