Erlang数据类型的表示和实现(1)——数据类型回顾
本文介绍 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)——数据类型回顾的更多相关文章
- SSIS 数据类型 第二篇:变量的数据类型
变量(Variable)用于存储在Package运行时用到的值,集成服务支持两种类型的变量:用户自定义的变量和系统变量,自定义的变量由用户来定义,系统变量由集成服务来定义. 变量的用途十分广泛,用于容 ...
- Java基础(34):Java中基本数据类型的包装类(主要为了不同数据类型之间更方便的进行转换)(Wrapper类)
相信各位小伙伴们对基本数据类型都非常熟悉,例如 int.float.double.boolean.char 等.基本数据类型是不具备对象的特性的,比如基本类型不能调用方法.功能简单...,为了让基本数 ...
- ArcGIS API for JavaScript 中的数据类型【vs】GPServer的数据类型
熟悉GPServer的同学肯定知道,GPServer在10.1的ArcMap后需要执行成功一次才能发布. 发布GPServer,可以是ArcMap的工具箱的工具,也可以是自己写的模型. 不管是ArcM ...
- c++ 常用数据类型,命名规则, 不常有数据类型
1. 常用数据类型 最大值0111111111111111 = 32767最小值1000000000000000 = -32768 short 最低16位 2**7 - 1 负值:反码 int 至少和 ...
- JavaScript的数据类型---最全,最详细的数据类型,高级的工程师从数据类型开始
一.基本数据类型 1.字符串数据类型 var hello="你好啊"; var hello='你好啊';示例:<script language="j ...
- char数据类型,编程能用的最小数据类型.
关于数据类型, char占1bit,8bites. signed代表有符号,包括正负数,和0; unsigned代表无符号,只包括0和整数; signed和unsigned的主要区别就是它们的最高位是 ...
- 建议2:注意Javascript数据类型的特殊性---(3)正确检测数据类型
使用typeof预算符返回一个用于识别其运算数类型的字符串.对于任何变量来说,使用typeof预算符总是以字符串的形式返回一下6种类型之一 number string boolean object f ...
- python基础(9):基本数据类型四(set集合)、基础数据类型补充、深浅拷贝
1. 基础数据类型补充 li = ["李嘉诚", "麻花藤", "⻩海峰", "刘嘉玲"] s = "_&qu ...
- Python之路-变量和基本数据类型详解(变量、数据类型、)
一.注释 注释的作用: 增加程序的可读性 作为调试用 提高团队的合作效率 注释的分类 1.单行注释 以井号(#)开头,右边的所有内容当做说明 2.多行注释 以三对单引号(’’’注释内容’’’)将注释包 ...
- 基本数据类型的值传递 和引用数据类型的引用传递 Day06
ValueTest1.java package com.sxt.valuetest; /* * 基本数据类型的传递:传递的是值得副本 */ public class ValueTest1 { publ ...
随机推荐
- 分布式唯一ID的几种生成方案
前言 在互联网的业务系统中,涉及到各种各样的ID,如在支付系统中就会有支付ID.退款ID等.那一般生成ID都有哪些解决方案呢?特别是在复杂的分布式系统业务场景中,我们应该采用哪种适合自己的解决方案是十 ...
- Mac生成APP图标和启动图的脚本
概述 之前用的一个批量导出APP图标和启动图的软件,今天发现收费了,于是自己造了个简单的轮子. 实现 Mac上的sips命令,可以很方便的帮助用户修改图片尺寸 Xcode里面的APP启动图资源包含两部 ...
- undefined reference to `sqrt'的问题
主要问题是math.h这个头文件虽然在/lib/include 下有定义,但是该文件内并没有sqrt()的定义.解决的办法是:在编译的时候在后面加上-lm,意思是链接到math函数库. 在gcc下用到 ...
- #leetcode刷题之路48-旋转图像
给定一个 n × n 的二维矩阵表示一个图像.将图像顺时针旋转 90 度.说明:你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵.请不要使用另一个矩阵来旋转图像.示例 1:给定 matrix ...
- Fiddler设置代理后,iphone手机无法访问网络的全面解决办法
好久不抓手机包,都有些忘记了,电脑上软件都在,原本是Fiddler4,现在已自动升级到V5. 入主题吧,首先Fiddler设置好代理,然后手机安装证书好了,设置手机代理,结果iphone无法访问网络, ...
- linux下pcf8563驱动时钟使用
环境: HelperA64开发板 Linux3.10内核 时间:2019.01.17 目标:PCF8563实时时钟驱动的使用 问题:因为pcf8563的驱动是linux内核自带的,网上也有很多分析的方 ...
- Scala(一):函数、流程控制、参数
Function:函数函数的定义: def 函数名(参数):返回类型=函数实现体 eg:def abs(x:Long) : Long = if(x >= 0) x else -x 你必须给出所有 ...
- (数据科学学习手札26)随机森林分类器原理详解&Python与R实现
一.简介 作为集成学习中非常著名的方法,随机森林被誉为“代表集成学习技术水平的方法”,由于其简单.容易实现.计算开销小,使得它在现实任务中得到广泛使用,因为其来源于决策树和bagging,决策树我在前 ...
- springMVC第一天——入门、整合与参数绑定
大纲摘要: 1.Springmvc介绍 2.入门程序 3.Springmvc架构讲解 a) 框架结构 b) 组件说明 4.Springmvc整合mybatis 5.参数绑定 乱码问题解决 a) Spr ...
- 洛咕 P2480 [SDOI2010]古代猪文
洛咕 P2480 [SDOI2010]古代猪文 题目是要求\(G^{\sum_{d|n}C^d_n}\). 用费马小定理\(G^{\sum_{d|n}C^d_n\text{mod 999911658} ...