阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Erlang中的Record详解

34次阅读
没有评论

共计 2302 个字符,预计需要花费 6 分钟才能阅读完成。

导读 这篇文章主要介绍了 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  
  % requires root access 
handle(Opts=#server_opts{}) -> 
  % Doesn't require root access

使用 Record[/yiji[

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

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-07-25发表,共计2302字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中