原文:
Erlang: An Introduction to Records
在Erlang内部只有两种混合的数据类型:List和Tuple,而这两种都不支持命名访问,所以如果没有额外的库的话想创建像PHP、Ruby或Python中的关联数组(Ruby中的Hash)是不可能的
在Ruby中我可以这样做:
server_opts = {:port => 8080, :ip => '127.0.0.1', :max_connections => 10}
在Erlang的语法级别不支持这种表达
为了避免这种限制,Erlang虚拟机提供了一个伪数据类型,称为Record
Record支持命名访问,后面我们会看到为什么我们称之为“伪”数据类型
定义Record
Record更类似于C中的struct,而不是关联数组,后者必须一开始就定义好内容并且只能保持数据
这里是一个服务器的连接选项的Record例子:
-module(my_server).
-record(server_opts,
{port,
ip="127.0.0.1",
max_connections=10}).
% The rest of your code goes here.
Record使用-record指令来声明,第一个参数是Record的名字,第二个参数是一个Tuple,Tuple包含了Record里的field和默认值
在这里我们定义了server_opts这个Record,它有三个field:端口、IP和最大连接数
没有默认的port,ip默认值为"127.0.0.1",max_connections默认值为10
创建Record
Record通过使用#符号来创建,下面是创建server_opts这个Record的实例的合法方式:
Opts1 = #server_opts{port=80}.
这段代码创建了一个server_opts Record,port设置为80,其他field使用默认值
Opts2 = #server_opts{port=80, ip="192.168.0.1"}.
这段代码创建了一个server_opts Record,但是ip设置为"192.168.0.1"
简而言之,当创建一个Record时,你可以包含任何field,省略的field将使用默认值
访问Record
Record的访问方式很笨拙,如果我想访问port这个field,我可以这样做:
Opts = #server_opts{port=80, ip="192.168.0.1"},
Opts#server_opts.port
每次你想访问一个Record时你都必须包含Record的名字,为什么要这样?
因为Record不是真正的内部数据类型,它只是编译器的小把戏。
在内部,Record是Tuple,如下:
{server_opts, 80, "127.0.0.1", 10}
编译器将Record的名字映射到Tuple里面
Erlang虚拟机记录了Record的定义,而编译器将所有的Record逻辑翻译为Tuple逻辑
因此,根本就没有Record类型,所以每次你访问一个Record时你必须告诉Erlang我们在用哪个Record(为了编译器爽,程序员变的很不爽)
更新Record
更新Record和创建Record很类似:
Opts = #server_opts{port=80, ip="192.168.0.1"},
NewOpts = Opts#server_opts{port=7000}.
这里首先创建一个server_opts Record
NewOpts = Opts#{port=7000}创建了一个Opts的副本,并指定port为7000并绑定到NewOpts
匹配Record和Guard语句
不谈模式匹配就不算Erlang
让我们来看看一个例子:
handle(Opts=#server_opts{port=8000}) ->
% do special port 8080 stuff
handle(Opts=#server_opts{} ->
% default stuff
Guard语句和上面的类似,例如绑定小于1024的端口通常需要root权限,所以我们可以这样做:
handle(Opts) when Opts#server_opts.port <= 1024 ->
% requires root access
handle(Opts=#server_opts{}) ->
% Doesn't require root access
使用Record
在我使用Erlang的有限的时间里,我发现Record主要用在两种场景
首先,Record用来保存状态,特别是在使用gen_server的behaviour时
由于Erlang不能全局保持状态,所以状态必须在方法之前传来传去
然后,Record可以用来保存配置选项,这可以认为是第一点的子集
尽管如此,Record也有一些限制,最明显的是不能在运行时添加和删除field,这和C的struct一样,Record的结构必须预先定义
如果你想在运行时添加和删除field,或者你在运行时才能确定有哪些field,这时你应该使用
dict而不是Record
分享到:
相关推荐
标题中的“<27>erlang record”可能指的是Erlang编程语言中的Record特性,它是一种数据结构,类似于结构体或者哈希表,用于组织和操作数据。在Erlang中,Record提供了一种方便的方式来定义和访问具有固定字段的数据...
主要介绍了Erlang中的Record详解,本文讲解了定义Record、创建Record、访问Record、更新Record、匹配Record和Guard语句、使用Record等内容,需要的朋友可以参考下
标题中的“erlang test 生成 dets”表明我们要讨论的是使用Erlang编程语言进行测试,并生成DETS(Disk-based Erlang Terms Storage)文件的过程。DETS是Erlang提供的一种持久化数据存储机制,类似于关系数据库的表,...
在Erlang Protobuffs项目中,`readme`文件是核心内容,它详细介绍了如何在Erlang环境中理解和使用协议缓冲区。 **一、协议缓冲区基础** 1. **数据序列化**:数据序列化是将结构化的对象转换为字节流的过程,便于在...
本文通过提供的Erlang代码片段,详细介绍了Erlang中模块声明、函数导出、文件包含、记录定义与操作、异常处理以及数值表示等核心概念。理解这些基础对于学习和使用Erlang非常重要。通过掌握这些基本知识,开发者可以...
下面将详细介绍Erlang模块的规则、特性、预处理以及相关函数。 4.1 模块规则 Erlang的程序源码被划分为多个模块,每个模块由一系列的特性声明和函数定义组成。每个语句以'.'结束。例如,下面是一个简单的模块示例:...
8. 语法和基本概念:Erlang有独特的语法,包括模块(module)、函数(function)、元组(tuple)、列表(list)、记录(record)等数据类型和构造。掌握基本语法是使用Erlang进行开发的基础。 由于文件描述中提到...
下面将详细介绍Erlang速查表中提到的一些关键知识点。 ### 变量和字符串 在Erlang中,变量名以大写字母开头,并且是动态类型的,意味着变量在赋值时不需要指定类型,类型将在运行时确定。字符串可以保存为整数列表...
- **手册目标**: 手册的目标是介绍Erlang的基本概念和语法,虽然内容覆盖不全面,但对于初学者来说足够入门。读者被鼓励进一步阅读其他资源来深入学习。 - **读者背景假设**: 假设读者有一定的计算机基础和基本的...
-record(person, {name, age}). ``` 这个记录定义了一个名为`person`的类型,包含两个字段:`name`和`age`。 **2. 继承与多态** Erlang不直接支持类和继承的概念,但它可以通过模式匹配和行为(behaviours)来实现...
《Erlang 参考手册》是一本全面介绍 Erlang 编程语言的官方文档。它旨在为开发者提供一个详尽的技术指南,帮助他们理解并熟练掌握 Erlang 的基本概念、语法结构以及高级特性。 **1.1.2 先决条件** 学习本手册之前...
- If you run change_log_format/1,2 and appender crashed, a restart from the supervisor will not record the latest format used. It will only use either the default format or the format used in the ...
Erlang 任务队列行为模块示例: -module(bruteforce_worker).-behaviour(task_queue).-export([ init/1, process_task/2, terminate/2, code_change/3 ]).-record(state, {}).init(_Args) -> #state{}.process_task...
Erlang Maps设计原由。17版后,还是需要多了解这个maps的。
本文详细介绍了Erlang中的基本元素操作,包括元组(tuple)、记录(record)、列表(list)和映射组(map)等。 首先来看元组(tuple)。元组是将固定数量的元素组合成一个单一实体的数据结构,它的一般形式是用大括号{}括...
在Erlang中实现特里树,我们可以定义一个记录(record)来表示节点,包括字符、子节点列表和是否为叶节点的标志。例如: ```erlang -record(trie_node, {char :: char(), children :: dict(), is_leaf :: boolean()...
该叉子将不再维护。 积极的发展已移至: 用法启动应用程序 application:start(emysql)....主机= string() 端口= integer() 数据库= string() 编码= atom() emysql:add_pool...记录类型 -record(ok_packet, {seq_nu