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更類似於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透過使用#符號來建立,下面是建立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的訪問方式很笨拙,如果我想訪問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很類似:
複製程式碼程式碼如下:
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
不談模式匹配就不算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[/yiji[
在我使用Erlang的有限的時間裡,我發現Record主要用在兩種場景.首先,Record用來儲存狀態,特別是在使用gen_server的behaviour時,由於Erlang不能全域性保持狀態,所以狀態必須在方法之前傳來傳去。然後,Record可以用來儲存配置選項,這可以認為是第一點的子集。儘管如此,Record也有一些限制,最明顯的是不能在執行時新增和刪除field,這和C的struct一樣,Record的結構必須預先定義,如果你想在執行時新增和刪除field,或者你在執行時才能確定有哪些field,這時你應該使用dict而不是Record。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69901823/viewspace-2887489/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Erlang中的if:讚美與非議
- S19格式檔案詳解(S-record) 分享
- rabbitmq解決erlang版本問題MQ
- Erlang/Elixir 中的 OTP 程式設計介紹程式設計
- JavaScript中的this詳解JavaScript
- SQL Server中的IO效能殺手Forwarded recordSQLServerForward
- vue中的插槽詳解Vue
- Python中的Super詳解Python
- Python中的列表詳解Python
- 詳解Python中的程式Python
- 詳解 Spark 中的 BucketingSpark
- Java中的ThreadLocal詳解Javathread
- Hive中的UDF詳解Hive
- 詳解Vue中的插槽Vue
- Netty中的ChannelHander詳解Netty
- Netty中的ByteBuf詳解Netty
- 移動端 CPU 的深度學習模型推理效能優化——NCHW44 和 Record 原理方法詳解深度學習模型優化
- JavaWeb中的Tomcat,Servlet詳解JavaWebTomcatServlet
- Java中的方法引用詳解Java
- JavaScript中的async/await詳解JavaScriptAI
- TypeScript中的函式詳解TypeScript函式
- MySQL 中的事務詳解MySql
- vue cli中的env詳解Vue
- gradle中的build script詳解GradleUI
- SAP 中的批次管理詳解
- JS中Object的API詳解JSObjectAPI
- Oracle中job的使用詳解Oracle
- 詳解 Java 中的物件克隆Java物件
- 詳解object detection中的mAPObject
- iOS中的Reference Counting詳解iOS
- 實戰 Java 16 值型別 Record - 2. Record 的基本用法Java型別
- CyberRT_recorder原始碼解讀以及record解析原始碼
- erlang聊天室
- CentOS 安裝ErlangCentOS
- C# 9.0中引入的新特性init和record的使用思考C#
- screen-record
- Active Record Associations
- react-recordReact