Запись
Модуль для работы с, определения и импорта записей.
Записи — это просто кортежи, где первый элемент — атом:
iex> Record.is_record({User, "john", 27})
true Этот модуль предоставляет удобства для работы с записями во время компиляции, где имена полей во время компиляции используются для манипулирования кортежами, обеспечивая быстрые операции на основе компактной структуры кортежей.
В Elixir записи чаще всего используются в двух ситуациях:
- для работы с короткими внутренними данными
- для взаимодействия с записями Erlang
Макросы defrecord/3 и defrecordp/3 могут быть использованы для создания записей, а extract/2 и extract_all/1 — для извлечения записей из файлов Erlang.
Типы
Типы могут быть определены для кортежей с помощью макроса record/2 (доступен только в типах). Этот макрос будет расширен до кортежа, как показано в примере ниже:
defmodule MyModule do
require Record
Record.defrecord(:user, name: "john", age: 25)
@type user :: record(:user, name: String.t(), age: integer)
# expands to: "@type user :: {:user, String.t(), integer}"
end Краткое описание
Защиты
- is_record(данные)
Проверяет, является ли заданные
dataзаписью.- is_record(данные, вид)
Проверяет, является ли заданные
dataзаписью видаkind.
Функции
- defrecord(имя, метка \\ nil, kv)
Определяет набор макросов для создания, доступа и сопоставления с образцом записи.
- defrecordp(имя, метка \\ nil, kv)
То же, что и
defrecord/3, но генерирует закрытые макросы.- extract(имя, параметры)
Извлекает информацию о записи из файла Erlang.
- extract_all(параметры)
Извлекает всю информацию о записях из файла Erlang.
Защиты
is_record(данные)
Проверяет, является ли заданные data записью.
Это реализовано как макрос, поэтому его можно использовать в условиях защиты.
Примеры
iex> record = {User, "john", 27}
iex> Record.is_record(record)
true
iex> tuple = {}
iex> Record.is_record(tuple)
false is_record(данные, вид)
Проверяет, является ли заданные data записью вида kind.
Это реализовано как макрос, поэтому его можно использовать в условиях защиты.
Примеры
iex> record = {User, "john", 27}
iex> Record.is_record(record, User)
true Функции
defrecord(имя, метка \\ nil, kv)
Определяет набор макросов для создания, доступа и сопоставления с образцом записи.
Имя сгенерированных макросов будет name (должно быть атомом). tag тоже атом и используется в качестве «метки» для записи (т.е., первого элемента кортежа записи); по умолчанию (если nil), он такой же, как name. kv — список ключевых слов name: default_value полей новой записи.
Генерируются следующие макросы:
-
name/0для создания новой записи с значениями по умолчанию для всех полей -
name/1для создания новой записи с заданными полями и значениями, для получения нулевого индекса заданного поля в записи или для преобразования заданной записи в список ключевых слов -
name/2для обновления существующей записи с заданными полями и значениями или для доступа к заданному полю в заданной записи
Все эти макросы являются общедоступными макросами (как определено defmacro).
См. раздел «Примеры» для примеров использования этих макросов.
Примеры
defmodule User do require Record Record.defrecord(:user, name: "meg", age: "25") end
В примере выше будет определен набор макросов под названием user, но с различными арностью для манипулирования базовой записью.
# Import the module to make the user macros locally available
import User
# To create records
record = user() #=> {:user, "meg", 25}
record = user(age: 26) #=> {:user, "meg", 26}
# To get a field from the record
user(record, :name) #=> "meg"
# To update the record
user(record, age: 26) #=> {:user, "meg", 26}
# To get the zero-based index of the field in record tuple
# (index 0 is occupied by the record "tag")
user(:name) #=> 1
# Convert a record to a keyword list
user(record) #=> [name: "meg", age: 26] Сгенерированные макросы также могут быть использованы для сопоставления с образцом записей и привязки переменных во время сопоставления:
record = user() #=> {:user, "meg", 25}
user(name: name) = record
name #=> "meg" По умолчанию Elixir использует имя записи как первый элемент кортежа (метка). Однако при определении записи можно указать другую метку, как в следующем примере, где мы используем Customer в качестве второго аргумента defrecord/3:
defmodule User do
require Record
Record.defrecord(:user, Customer, name: nil)
end
require User
User.user() #=> {Customer, nil} Определение извлеченных записей с анонимными функциями в значениях
Если запись определяет анонимную функцию в значениях по умолчанию, будет поднята ошибка ArgumentError. Это может произойти непреднамеренно при определении записи после ее извлечения из библиотеки Erlang, которая использует анонимные функции для значений по умолчанию.
Record.defrecord(:my_rec, Record.extract(...)) #=> ** (ArgumentError) invalid value for record field fun_field, #=> cannot escape #Function<12.90072148/2 in :erl_eval.expr/5>.
Чтобы обойти эту ошибку, переопределите поле с вашей собственной функцией &M.f/a, например:
defmodule MyRec do
require Record
Record.defrecord(:my_rec, Record.extract(...) |> Keyword.merge(fun_field: &__MODULE__.foo/2))
def foo(bar, baz), do: IO.inspect({bar, baz})
end defrecordp(имя, метка \\ nil, kv)
То же, что и defrecord/3, но генерирует закрытые макросы.
extract(имя, параметры)
Спецификации
extract(name :: atom(), keyword()) :: keyword()
Извлекает информацию о записи из файла Erlang.
Возвращает скопированное выражение, содержащее поля в виде списка кортежей.
name, которое является именем извлеченной записи, должно быть атомом во время компиляции.
Параметры
Эта функция принимает следующие параметры, которые являются взаимоисключающими (т.е., только один из них может быть использован в одном вызове):
-
:from- (двоичное представление пути к файлу) путь к файлу Erlang, содержащему определение записи для извлечения; с этим параметром функция использует тот же поиск путей, что и атрибут-include, используемый в модулях Erlang. -
:from_lib- (двоичное представление пути к файлу) путь к файлу Erlang, содержащему определение записи для извлечения; с этим параметром функция использует тот же поиск путей, что и атрибут-include_lib, используемый в модулях Erlang. -
:includes- (список каталогов в виде двоичных данных) если извлекаемая запись зависит от относительных включений, этот параметр позволяет разработчикам указать каталог, в котором находятся эти относительные включения. -
:macros- (список ключевых слов имен макросов и значений) если извлекаемая запись зависит от значений макросов, этот параметр позволяет установить значения этих макросов.
Эти параметры должны быть литералами (включая двоичные значения) во время компиляции.
Примеры
iex> Record.extract(:file_info, from_lib: "kernel/include/file.hrl") [ size: :undefined, type: :undefined, access: :undefined, atime: :undefined, mtime: :undefined, ctime: :undefined, mode: :undefined, links: :undefined, major_device: :undefined, minor_device: :undefined, inode: :undefined, uid: :undefined, gid: :undefined ]
extract_all(параметры)
Спецификации
extract_all(keyword()) :: [{name :: atom(), keyword()}] Извлекает всю информацию о записях из файла Erlang.
Возвращает список ключевых слов кортежей {record_name, fields}, где record_name — имя извлеченной записи, а fields — список кортежей {field, value} полей для этой записи.
Параметры
Эта функция принимает следующие параметры, которые являются взаимоисключающими (т.е., только один из них может быть использован в одном вызове):
-
:from- (двоичное представление пути к файлу) путь к файлу Erlang, содержащему определения записей для извлечения; с этим параметром функция использует тот же поиск путей, что и атрибут-include, используемый в модулях Erlang. -
:from_lib- (двоичное представление пути к файлу) путь к файлу Erlang, содержащему определения записей для извлечения; с этим параметром функция использует тот же поиск путей, что и атрибут-include_lib, используемый в модулях Erlang.
Эти параметры должны быть литералами (включая двоичные значения) во время компиляции.
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.9.4/Record.html