• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    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

    您可能感兴趣的文章:
    • Go/Python/Erlang编程语言对比分析及示例代码
    • python读取excel表格生成erlang数据
    • Erlang实现的一个Web服务器代码实例
    • Erlang初学:Erlang的一些特点和个人理解总结
    • CentOS 6.5源码安装Erlang教程
    • ERLANG和PYTHON互通实现过程详解
    上一篇:Erlang中遍历取出某个位置的最大值代码
    下一篇:Erlang实现的一个Web服务器代码实例
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    Erlang中的Record详解 Erlang,中的,Record,详解,Erlang,