A record is a data structure for storing a fixed number of
elements. It has named fields and is similar to a struct in C.
Record expressions are translated to tuple expressions during
compilation. Therefore, record expressions are not understood by
the shell unless special actions are taken. For details, see the
More examples are provided in
A record definition consists of the name of the record,
followed by the field names of the record. Record and field names
must be atoms. Each field can be given an optional default value.
If no default value is supplied,
-record(Name, {Field1 [= Value1], ... FieldN [= ValueN]}).
A record definition can be placed anywhere among the attributes and function declarations of a module, but the definition must come before any usage of the record.
If a record is used in several modules, it is recommended that the record definition is placed in an include file.
The following expression creates a new
#Name{Field1=Expr1,...,FieldK=ExprK}
The fields can be in any order, not necessarily the same order as in the record definition, and fields can be omitted. Omitted fields get their respective default value instead.
If several fields are to be assigned the same value, the following construction can be used:
#Name{Field1=Expr1,...,FieldK=ExprK, _=ExprL}
Omitted fields then get the value of evaluating
Example:
-record(person, {name, phone, address}). ... lookup(Name, Tab) -> ets:match_object(Tab, #person{name=Name, _='_'}).
Expr#Name.Field
Returns the value of the specified field.
The following expression returns the position of the specified field in the tuple representation of the record:
#Name.Field
Example:
-record(person, {name, phone, address}). ... lookup(Name, List) -> lists:keysearch(Name, #person.name, List).
Expr#Name{Field1=Expr1,...,FieldK=ExprK}
Since record expressions are expanded to tuple expressions, creating records and accessing record fields are allowed in guards. However all subexpressions, for example, for field initiations, must be valid guard expressions as well.
Examples:
handle(Msg, State) when Msg==#msg{to=void, no=3} ->
...
handle(Msg, State) when State#state.running==true ->
...
There is also a type test BIF
Example:
is_person(P) when is_record(P, person) -> true; is_person(_P) -> false.
A pattern that matches a certain record is created in the same way as a record is created:
#Name{Field1=Expr1,...,FieldK=ExprK}
In this case, one or more of
Beginning with Erlang/OTP R14, parentheses when accessing or updating nested records can be omitted. Assume the following record definitions:
-record(nrec0, {name = "nested0"}). -record(nrec1, {name = "nested1", nrec0=#nrec0{}}). -record(nrec2, {name = "nested2", nrec1=#nrec1{}}). N2 = #nrec2{},
Before R14, parentheses were needed as follows:
"nested0" = ((N2#nrec2.nrec1)#nrec1.nrec0)#nrec0.name, N0n = ((N2#nrec2.nrec1)#nrec1.nrec0)#nrec0{name = "nested0a"},
Since R14, the following can also be written:
"nested0" = N2#nrec2.nrec1#nrec1.nrec0#nrec0.name, N0n = N2#nrec2.nrec1#nrec1.nrec0#nrec0{name = "nested0a"},
Record expressions are translated to tuple expressions during compilation. A record defined as:
-record(Name, {Field1,...,FieldN}).
is internally represented by the tuple:
{Name,Value1,...,ValueN}
Here each
To each module using records, a pseudo function is added during compilation to obtain information about records:
record_info(fields, Record) -> [Field] record_info(size, Record) -> Size
In addition,