Erlang里的Record

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

  1. server_opts = {:port => 8080, :ip => ‘127.0.0.1‘, :max_connections => 10}

在Erlang的语法级别不支持这种表达

为了避免这种限制,Erlang虚拟机提供了一个伪数据类型,称为Record 
Record支持命名访问,后面我们会看到为什么我们称之为“伪”数据类型

定义Record 
Record更类似于C中的struct,而不是关联数组,后者必须一开始就定义好内容并且只能保持数据 
这里是一个服务器的连接选项的Record例子:

  1. -module(my_server).
  2. -record(server_opts,
  3. {port,
  4. ip="127.0.0.1",
  5. max_connections=10}).
  6. % 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的实例的合法方式:

  1. Opts1 = #server_opts{port=80}.

这段代码创建了一个server_opts Record,port设置为80,其他field使用默认值

  1. 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,我可以这样做:

  1. Opts = #server_opts{port=80, ip="192.168.0.1"},
  2. Opts#server_opts.port

每次你想访问一个Record时你都必须包含Record的名字,为什么要这样? 
因为Record不是真正的内部数据类型,它只是编译器的小把戏。

在内部,Record是Tuple,如下:

  1. {server_opts, 80, "127.0.0.1", 10}

编译器将Record的名字映射到Tuple里面 
Erlang虚拟机记录了Record的定义,而编译器将所有的Record逻辑翻译为Tuple逻辑 
因此,根本就没有Record类型,所以每次你访问一个Record时你必须告诉Erlang我们在用哪个Record(为了编译器爽,程序员变的很不爽)

更新Record 
更新Record和创建Record很类似:

  1. Opts = #server_opts{port=80, ip="192.168.0.1"},
  2. NewOpts = Opts#server_opts{port=7000}.

这里首先创建一个server_opts Record 
NewOpts = Opts#{port=7000}创建了一个Opts的副本,并指定port为7000并绑定到NewOpts

匹配Record和Guard语句 
不谈模式匹配就不算Erlang 
让我们来看看一个例子:

  1. handle(Opts=#server_opts{port=8000}) ->
  2. % do special port 8080 stuff
  3. handle(Opts=#server_opts{} ->
  4. % default stuff

Guard语句和上面的类似,例如绑定小于1024的端口通常需要root权限,所以我们可以这样做:

  1. handle(Opts) when Opts#server_opts.port <= 1024 ->
  2. % requires root access
  3. handle(Opts=#server_opts{}) ->
  4. % Doesn‘t require root access

使用Record 
在我使用Erlang的有限的时间里,我发现Record主要用在两种场景 
首先,Record用来保存状态,特别是在使用gen_server的behaviour时 
由于Erlang不能全局保持状态,所以状态必须在方法之前传来传去 
然后,Record可以用来保存配置选项,这可以认为是第一点的子集 
尽管如此,Record也有一些限制,最明显的是不能在运行时添加和删除field,这和C的struct一样,Record的结构必须预先定义 
如果你想在运行时添加和删除field,或者你在运行时才能确定有哪些field,这时你应该使用dict而不是Record

时间: 2024-09-27 04:32:47

Erlang里的Record的相关文章

说说erlang tuple和record结构

erlang有两种复合结构,tuple和list,两者的区别是tuple子元素的个数是固定不变的,声明后就不能改变了:而list是可变的,可以通过[H|T]来取出或插入新元素.record有点像C/C++里面的结构体,实际上是语法糖,方便我们的开发,代码汇编时转成tuple表达形式. Tuple tuple的表示方法如: {Term1,...,TermN} 下面以例子说明erlang tuple及一些基本操作: 1> A = {1,2}. {1,2} 2> tuple_size(A). 2 3

Erlang中的record与宏

http://www.cnblogs.com/me-sa/archive/2011/07/20/erlang0006.html 在Erlang中使用Tuple ,数据项的顺序\数量都是确定的,一旦数据项顺序调整或者增减字段,都容易出现badmatch. 同时一些常量如果硬编码到代码中,一旦数值变化,要想全部可靠的替换成新的数值是一个困难的事情. 这两种数据层面的变化,在Erlang中对应的解决方案是: record  Macro record   在代码中我们创建一个record:   -rec

Erlang 摘要

世界是并行的,Erlang程序反应了我们思考和交流的方式,人作为个体通过发送消息进行交流,如果有人死亡,其他人会注意到.Erlang里的模块类相当于OOPL中的类,进程相当于OOPL里的对象或类实例.并发编程可以用来提升性能,创建可扩展和容错的系统,以及编写清晰和可理解的程序来控制现实世界里的应用. 并发程序是以一种并发编程语言编写的程序,并发编程语言拥有用于编写并发程序的语言结构.Erlang的并发程序是由互相通信的多组顺序进程组成,一个进程就是一个轻量级的虚拟机,可以执行单个的Erlang函

[Erlang 0110] Erlang Abstract Format , Part 1

Erlang Abstract Format并不难懂,只是枯燥一点罢了,如果把Abstract Format的文档翻译出来,其实就是Erlang教科书中语法入门的部分. Erlang Abstract Format实际上是用Erlang代码的AST,下面通过一些真切的实例代码了解一下它的一些细节. 首先,Erlang Abstract Format里面包含一些概念,我会在下面的描述中把涉及到的概念字体加粗.请注意概念之间的层次关系.Erlang代码本身使用非常扁平的module组织,每一个mod

[Erl_Question11] 那些经历过的Erlang小坑11-20

11.每次重装系统时都会重新安装Erlang,Ubuntu安装sh秒杀一切. https://gist.github.com/zhongwencool/11174620 12. Erlang Shell隐藏的小技巧: f(). %%把所有绑定变量释放掉 f(Val). %%把Val变量释放掉 v(Line). %%把Line行函数重新执行一次 v(-1). %%把前一行的函数重新执行一次 rr(Module).%%把Module中的Record加载到Shell中,[超有用] rr("*/*&qu

erlang 游戏服务器开发

http://blog.csdn.net/slmeng2002/article/details/5532771 最近关注erlang游戏服务器开发  erlang大牛写的游戏服务器值得参考 介绍本文以我的OpenPoker项目为例子,讲述了一个构建超强伸缩性的在线多游戏玩家系统.OpenPoker是一个超强多玩家纸牌服务器,具有容错.负载均衡和无限伸缩性等特性.源代码位于我的个人站点上,大概10,000行代码,其中1/3是测试代码. 在OpenPoker最终版本敲定之前我做了大量调研,我尝试了D

Erlang点滴--杀死gen_server

前天同事碰到了一个问题:他为游戏写了一个模拟客户端的机器人程序,用的是gen_server行为.但是他启动这些机器人时并没有通过监控树,而是直接在Shell下启动了若干个.然后他就发现如果其中一个机器人进程挂掉的话,所有的机器人都会跟着挂掉. 当他把问题告诉我时我第一反应就是Shell挂掉了,因为所有的机器人都是在Shell下用start_link启动的,也就是说所有的机器人进程都和Shell进程建立了连接.因此如果其中一个机器人挂掉,它会向Shell发送EXIT消息导致Shell挂掉,Shel

Erlang ETS Table

不需要显示用锁,插入和查询时间不仅快而且控制为常量,这就是Erlang的ETS Table. 为什么而设计? Erlang中可以用List表达集合数据,但是如果数据量特别大的话在List中访问元素就会变慢了;这种主要是由于List的绝大部分操作都是基于遍历完成的. Erlang的设计目标是软实时(参考:http://en.wikipedia.org/wiki/Real-time_computing),在大量数据中检索的时间不仅要快而且要求是常量.为了解决快速查 询的问题,Erlang提供的机制就

把宏添加到自定义Ribbon并在所有Excel里运行它的方法

1. 先打开一个空Excel文档,进入File-Options-Customize Ribbon,在右边 Main Tabs里找到Developer并勾选,这样在Excel里将可以看到Developer这个Tab 2. 点击下面的New Tab创建一个新的Tab,并在这个Tab下面创建一个Group备用,Tab和 Group的名字可以填上想要的名字,如Tab为May Macros,Group为Production Status 3. 在Developer里找到Record Macro,指定Mar