当前位置: 首页 > 编程笔记 >

Erlang中的Record详解

西门智
2023-03-14
本文向大家介绍Erlang中的Record详解,包括了Erlang中的Record详解的使用技巧和注意事项,需要的朋友参考一下

在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

 类似资料:
  • 本文向大家介绍详谈innodb的锁(record,gap,Next-Key lock),包括了详谈innodb的锁(record,gap,Next-Key lock)的使用技巧和注意事项,需要的朋友参考一下 Record lock单条索引记录上加锁,record lock锁住的永远是索引,而非记录本身,即使该表上没有任何索引,那么innodb会在后台创建一个隐藏的聚集主键索引,那么锁住的就是这个隐

  • 记录 描述: 目录结构 . ├── Controller ├── Install ├── Libs 核心实现库 ├── Records 记录实体类 ├── Model ├── Service 服务 └── Uninstall 使用指南 1.创建你的记录实体类 在 Record/Records/ 目录下创建消息实体类,并继承 Record\Libs\Record 类 <?php namesp

  • 实现三种方式的屏幕录制,可以录制屏幕上的任意操作。 代码包包括三份代码:AVAssetWriterDemo、ScreenCapture、ScreenRecorderDemo。其中AVAssetWriterDemo可以录制屏幕上一些输入文字、点击按钮等等操作。ScreenCapture 和 ScreenRecorderDemo 录制在屏幕上绘制线条的过程。ScreenCapature 采用的是每截取

  • 本文向大家介绍Erlang中的OTP简介,包括了Erlang中的OTP简介的使用技巧和注意事项,需要的朋友参考一下 OTP包含了一组库和实现方式,可以构建大规模、容错和分布式的应用程序,包含了许多强大的工具,能够实现H248,SNMP等多种协议,核心概念是OTP行为,可以看作一个用回调函数作为参数的应用程序框架,类似一个J2EE容器。行为负责解决问题的非函数部分,回调函数负责解决函数部分。   通

  • 主要内容:Java16 Record类的示例Java 14 引入了一个新的类类型Record作为预览功能,以促进不可变数据对象的创建。Java 15 进一步增强了记录类型。在 Java 16 中,Record现在是 JDK 的标准功能。 Java16 Record类的示例 ApiTester.java 编译并运行程序 输出结果为  

  • 主要内容:Java15 Record类的示例Java 14 引入了一个新的类类型Record作为预览功能,以增强不可变数据对象的创建。Java 15 进一步增强了Record类型。它仍然是一个预览功能。 Record 对象具有隐式构造函数,所有参数都作为字段变量。 Record 对象具有每个字段变量的隐式字段 getter 方法。 Record 对象具有针对每个字段变量的隐式字段设置器方法。 Record 对象隐含了 hashCode()、