Есть ли способ иметь записи Elixir без значений по умолчанию?

Фон

Я пытаюсь найти дешевый и простой способ создания новых типов в Эликсире, и Рекорды кажется именно тем, что мне нужно.

Проблема

Однако записи Elixir требуют, чтобы они определяли значения по умолчанию. Мало того, он также позволяет создавать пустые записи (которые затем будут заполнены указанными значениями по умолчанию).

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

Теперь я понимаю, что это, вероятно, хорошо продуманный выбор, скорее всего, чтобы он мог хорошо взаимодействовать с записями Erlang, но это вызывает проблему с удобством использования с моей стороны: это позволяет создавать недействительные данные.

Вопросы

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

Я лично ничего не нашел, сейчас у меня такое чувство, что мое единственное решение - написать свой собственный макрос.

  • Есть ли способ, чтобы записи не принимали значения по умолчанию?
  • Если нет, то какие библиотеки сообщества могут помочь в создании нового типа?

Просто удостоверяюсь, но вы изучили структуры и атрибут @enforce_keys?

Everett 22.03.2022 12:03

Да, у меня есть. Вы можете сделать это, но здесь задействовано много шаблонов, поэтому моя идея для макроса.

Flame_Phoenix 22.03.2022 14:40

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

Fabri Damazio 28.03.2022 02:04

Мы согласны с этим!

Flame_Phoenix 28.03.2022 11:04
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
4
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Отвечать

  1. Есть ли способ, чтобы записи не принимали значения по умолчанию?

Нет. Это невозможно с Records. Записи никогда не предназначались для этого варианта использования, и внедрение в них этой абстракции только усложнило бы ситуацию. Хотя можно было бы использовать метод-оболочку new, это все равно будет много шаблонного, и вся проверка типа будет на пользователе.

  1. На момент написания этой статьи их нет. Однако в другом посте я создал макрос, который достигает этой цели: https://elixirforum.com/t/how-to-define-macro-for-a-new-type/46852/10?u=fl4m3ph03n1x

В этом посте я предлагаю API, а затем улучшаю его с помощью сообщества. Для тех из вас, кому любопытно, его можно использовать следующим образом:

тип.ex

defmodule Type do
  import NewType

  deftype(Name, String.t())
end

test.ex

defmodule Test do
  alias Type.Name

  @spec print(Name.t()) :: binary
  def print(name), do: Name.extract(name)

  def run_1 do
    # dialyzer complains !
    Name.new(1)
  end

  def run_2 do
    # dialyzer complains !
    print("john")
  end

  @spec run_3 :: binary
  def run_3 do
    print(Name.new("dow"))
  end
end

Другие вопросы по теме