Spec-Zone.ru › Elixir 1.16

Source Record

Модуль для работы с, определения и импорта записей.

Записи — это просто кортежи, где первый элемент — атом:

iex> Record.is_record({User, "john", 27})
true

Этот модуль предоставляет удобства для работы с записями на этапе компиляции, где имена полей на этапе компиляции используются для манипулирования кортежами, обеспечивая быстрые операции над компактной структурой кортежей.

В Elixir записи в основном используются в двух ситуациях:

  1. для работы с короткими внутренними данными
  2. для взаимодействия с записями 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

Рефлексия

Список всех записей в модуле, если таковые имеются, можно получить, прочитав атрибут модуля @__records__. Он возвращает список карт с типом записи, именем, меткой и полями. Атрибут доступен только внутри определения модуля.

Резюме

Защитные условия

is_record(данные)

Проверяет, является ли данное data записью.

is_record(данные, тип)

Проверяет, является ли заданные data записью типа kind.

Функции

defrecord(имя, метка \\ nil, kv)

Определяет набор макросов для создания, доступа и сопоставления по шаблону с записью.

defrecordp(имя, метка \\ nil, kv)

То же, что и defrecord/3, но генерирует частные макросы.

extract(имя, параметры)

Извлекает информацию о записи из файла Erlang.

extract_all(параметры)

Извлекает всю информацию о записях из файла Erlang.

Защитные условия

is_record(данные)Source

Проверяет, является ли заданные data записью.

Это реализовано как макрос, поэтому его можно использовать в условиях защиты.

Примеры

Record.is_record({User, "john", 27})
#=> true

Record.is_record({})
#=> false

is_record(данные, тип)Source

Проверяет, является ли заданные data записью типа kind.

Это реализовано как макрос, поэтому его можно использовать в условиях защиты.

Примеры

iex> record = {User, "john", 27}
iex> Record.is_record(record, User)
true

Функции

defrecord(имя, метка \\ nil, kv)Source

Определяет набор макросов для создания, доступа и сопоставления по шаблону с записью.

Имя сгенерированных макросов будет 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)Source

То же, что и defrecord/3, но генерирует частные макросы.

extract(имя, параметры)Source

@spec 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(параметры)Source

@spec extract_all(keyword()) :: [{name :: atom(), keyword()}]

Извлекает всю информацию о записях из файла Erlang.

Возвращает список ключевых слов кортежей {record_name, fields}, где record_name — имя извлеченной записи, а fields — список кортежей {field, value}, представляющих поля для этой записи.

Параметры

Принимает те же параметры, что и Record.extract/2.

Download ePub version

Built using ExDoc (v0.32.2) for the Elixir programming language

© 2012-2024 The Elixir Team
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.16.3/Record.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API