Запись
Модуль для работы с, определения и импорта записей.
Записи — это просто кортежи, где первый элемент — атом:
iex> Record.is_record {User, "john", 27}
true Этот модуль предоставляет удобства для работы с записями во время компиляции, где имена полей во время компиляции используются для управления кортежами, обеспечивая быстрые операции на основе компактной структуры кортежей.
В Elixir записи в основном используются в двух ситуациях:
- для работы с короткими внутренними данными
- для взаимодействия с Erlang-записями
Макросы defrecord/3 и defrecordp/3 могут быть использованы для создания записей, а extract/2 может быть использован для извлечения записей из файлов 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 Обзор
Функции
- defrecord(name, tag \\ nil, kv)
-
Определяет набор макросов для создания и доступа к записи
- defrecordp(name, tag \\ nil, kv)
-
То же, что и
defrecord/3, но генерирует приватные макросы - extract(name, opts)
-
Извлекает информацию о записи из файла Erlang
- extract_all(opts)
-
Извлекает всю информацию о записях из файла Erlang
- is_record(data)
-
Проверяет, является ли данная
dataзаписью - is_record(data, kind)
-
Проверяет, является ли данная
dataзаписью типаkind
Функции
defrecord(name, tag \\ nil, kv) (макрос)
Определяет набор макросов для создания и доступа к записи.
Макросы будут иметь name, тег (который по умолчанию) — имя, если не указано, и набор полей, заданный kv.
Примеры
defmodule User do require Record Record.defrecord :user, [name: "meg", age: "25"] end
В примере выше будет определен набор макросов с именем 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}
# 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 использует имя записи в качестве первого элемента кортежа (тега). Но его можно изменить на что-то другое:
defmodule User do
require Record
Record.defrecord :user, User, name: nil
end
require User
User.user() #=> {User, 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(name, tag \\ nil, kv) (макрос)
То же, что и defrecord/3, но генерирует приватные макросы.
extract(name, opts)
Извлекает информацию о записи из файла Erlang.
Возвращает выражение с цитированием, содержащее поля в виде списка кортежей. Ожидает, что имя записи будет атомом, а путь к библиотеке — строкой во время расширения.
Примеры
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(opts)
Извлекает всю информацию о записях из файла Erlang.
Возвращает список ключевых слов, содержащий имена извлеченных записей в качестве ключей и списки кортежей, описывающих поля, в качестве значений. Ожидает именованный аргумент :from или :from_lib, которые соответствуют атрибутам include или include_lib из модулей Erlang соответственно.
is_record(data) (макрос)
Проверяет, является ли данная data записью.
Это реализовано как макрос, так как он может использоваться в условиях охраны.
Примеры
iex> record = {User, "john", 27}
iex> Record.is_record(record)
true
iex> tuple = {}
iex> Record.is_record(tuple)
false is_record(data, kind) (макрос)
Проверяет, является ли данная data записью типа kind.
Это реализовано как макрос, так как он может использоваться в условиях охраны.
Примеры
iex> record = {User, "john", 27}
iex> Record.is_record(record, User)
true
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.3.4/Record.html