Erlang中的Record详解

 更新时间:2015年04月29日 10:21:54   投稿:junjie  
这篇文章主要介绍了Erlang中的Record详解,本文讲解了定义Record、创建Record、访问Record、更新Record、匹配Record和Guard语句、使用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

相关文章

  • Erlang初学:Erlang的一些特点和个人理解总结

    Erlang初学:Erlang的一些特点和个人理解总结

    这篇文章主要介绍了Erlang初学:Erlang的一些特点和个人理解总结,本文总结了函数式编程、一切都是常量、轻量进程、进程端口映射及典型缺点等内容,需要的朋友可以参考下
    2015-02-02
  • erlang on_load_function_failed排查过程解析

    erlang on_load_function_failed排查过程解析

    这篇文章主要为大家介绍了erlang on_load_function_failed的排查过程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • Erlang中的基本元素操作小结

    Erlang中的基本元素操作小结

    这篇文章主要介绍了Erlang中的基本元素操作小结,本文讲解了元组(tuple)、记录(record)、列表(list)、映射组(map)等内容,需要的朋友可以参考下
    2015-03-03
  • Erlang并发编程介绍

    Erlang并发编程介绍

    这篇文章主要介绍了Erlang并发编程介绍,本文讲解了进程的创建 、进程间通信、超时设置以及给出代码实例,需要的朋友可以参考下
    2015-01-01
  • Erlang中的匹配模式总结

    Erlang中的匹配模式总结

    这篇文章主要介绍了Erlang中的匹配模式总结,本文讲解了赋值时匹配、流程控制中的匹配、消息传递匹配等内容,需要的朋友可以参考下
    2015-01-01
  • Erlang中的并发程序简介

    Erlang中的并发程序简介

    这篇文章主要介绍了Erlang中的并发程序简介,本文讲解了Erlang中基本的并发函数、并发程序模板、程序在出错时立即崩溃的优点、为了在互联网上执行并发程序等内容,需要的朋友可以参考下
    2015-03-03
  • Erlang中的注册进程使用实例

    Erlang中的注册进程使用实例

    这篇文章主要介绍了Erlang中的注册进程使用实例,本文给出正常进程通信实例和使用使用注册进程通信实例,需要的朋友可以参考下
    2015-02-02
  • Erlang中的函数与流程控制介绍

    Erlang中的函数与流程控制介绍

    这篇文章主要介绍了Erlang中的函数与流程控制介绍,本文先是讲解了函数的一些知识,然后讲解了case语句和if语句及算术表达式等内容,需要的朋友可以参考下
    2015-01-01
  • Erlang中3种生成随机数的方法

    Erlang中3种生成随机数的方法

    这篇文章主要介绍了Erlang中3种生成随机数的方法,它们分别是random:uniform()、erlang:now()、crypto:strong_rand_bytes(N),需要的朋友可以参考下
    2015-01-01
  • Erlang程序设计(第2版)读书笔记:Erlang安装和基础语法

    Erlang程序设计(第2版)读书笔记:Erlang安装和基础语法

    这篇文章主要介绍了Erlang程序设计(第2版)读书笔记:Erlang安装和基础语法,需要的朋友可以参考下
    2015-02-02

最新评论