广告位联系
返回顶部
分享到

Erlang中的Record的介绍

Erlang 来源:转载 作者:秩名 发布时间:2021-06-16 09:35:35 人浏览
摘要

在Erlang内部只有两种混合的数据类型:List和Tuple,而这两种都不支持命名访问,所以如果没有额外的库的话想创建像PHP、Ruby或Python中的关联数组(Ruby中的Hash)是不可能的 在Ruby中我可以这样做: server_opts = {:port = 8080, :ip = 127.0.0.1, :max_co

在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


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。

您可能感兴趣的文章 :

原文链接 : https://www.jb51.net/article/65148.htm
    Tag :
相关文章
  • 从入门到精通:RabbitMQ的详细介绍

    从入门到精通:RabbitMQ的详细介绍
    1. 浅浅道来 1.1 什么是中间件? IDC(互联网数据中心)的定义:中间件是一种独立的系统软件服务程序,分布式应用软件借助这种软件在不
  • 深入浅析RabbitMQ镜像集群原理

    深入浅析RabbitMQ镜像集群原理
    集群架构 RabbitMQ 集群是一个或多个节点的逻辑分组,集群中的每个节点都是对等的 每个节点共享所有的用户,虚拟主机,队列,交换器,绑
  • Erlang中的Record的介绍
    在Erlang内部只有两种混合的数据类型:List和Tuple,而这两种都不支持命名访问,所以如果没有额外的库的话想创建像PHP、Ruby或Python中的关联
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计