There are only two mixed data types within Erlang: list and tuple, neither of which supports named access, so it is not possible to create associative arrays in PHP, Ruby, or Python (hash in Ruby) without additional libraries.
I can do this in Ruby:
Copy Code code as follows:
server_opts = {:p ort => 8080,: IP => ' 127.0.0.1 ',: Max_connections => 10}
This expression is not supported at the syntax level of Erlang
To avoid this limitation, Erlang virtual machines provide a pseudo data type called a record
The record supports named Access, and later we see why we call it a "pseudo" data type
Define a record
The record is more like the struct in C than the associative array, which must be defined at the outset and can only hold the data
Here is a record example of a server's connectivity option:
Copy Code code as follows:
-module (My_Server).
-record (Server_opts,
{port,
Ip= "127.0.0.1",
MAX_CONNECTIONS=10}).
% of the rest of your code goes here.
The record uses the-RECORD directive to declare that the first argument is the name of the record, and the second parameter is a tuple,tuple containing the field and default values
Here we define the server_opts record, which has three field: Port, IP, and maximum number of connections
There is no default port,ip default is "127.0.0.1", max_connections default value is 10
Create a record
The record is created by using the # symbol, and the following is the legal way to create an instance of server_opts this record:
Copy Code code as follows:
Opts1 = #server_opts {port=80}.
This code creates a server_opts Record,port set to 80, and the other field uses the default value
Opts2 = #server_opts {port=80, ip= "192.168.0.1"}.
This code creates a server_opts record, but IP is set to "192.168.0.1"
In short, when you create a record, you can include any field, and the omitted field will use the default value
Accessing the Record
The record is very awkward to access, and if I want to visit port this field, I can do this:
Copy Code code as follows:
Opts = #server_opts {port=80, ip= "192.168.0.1"},
Opts#server_opts.port
Every time you want to visit a record you must include the name of the record, why?
Because the record is not really an intrinsic data type, it is just a trick of the compiler.
Inside, the record is tuple, as follows:
Copy Code code as follows:
{server_opts, 80, "127.0.0.1", 10}
The compiler maps the name of the record to the tuple
The Erlang virtual machine records the definition of the record, and the compiler translates all the recording logic into tuple logic
Therefore, there is no record type at all, so every time you visit a record you have to tell Erlang which record we're using (for the compiler, the programmer gets very upset)
Update record
Updating a record is similar to creating a record:
Copy Code code as follows:
Opts = #server_opts {port=80, ip= "192.168.0.1"},
newopts = opts#server_opts{port=7000}.
Here we first create a server_opts record
Newopts = opts#{port=7000} Creates a copy of the Opts and specifies that port is 7000 and bound to newopts
Matching record and guard statements
It's not Erlang if you don't talk about pattern matching.
Let's take a look at an example:
Copy Code code as follows:
Handle (opts= #server_opts {port=8000})->
% do special port 8080 stuff
Handle (opts= #server_opts {}->
% Default Stuff
The guard statement is similar to the above, for example, a port with a binding less than 1024 usually requires root permission, so we can do this:
Copy Code code as follows:
Handle (Opts) when Opts#server_opts.port <= 1024->
% requires root access
Handle (opts= #server_opts {})->
% doesn ' t require root access
Using the Record
In my limited time using Erlang, I found that the record was mainly used in two scenarios
first, the save state is used, especially when using gen_server behaviour
because Erlang cannot be globally persisted. So the state must be passed before the method
then the record can be used to save the configuration options, which can be considered a 1th subset
Nevertheless, the record has some limitations, most notably, it is not possible to add and delete field at run time, as in C's struct, The structure of the record must be predefined
If you want to add and delete field at run time, or you can determine which field is at run time, you should use Dict instead of a record