Зачитать

Диапазон эликсира - странный опыт перечисления

Вы только незнакомец, пока не узнаете

В этой статье рассказывается об одном из моих странных опытов с Эликсиром.

Как я испытал?

В одном из моих проектов мне нужно повторять вызов функции определенное количество раз.

Сразу загорелась идея использовать дальность. Все мы знаем, что диапазон в Elixir представлен как ..

Однако внутренний диапазон - это тип данных struct %Range{}.

Надеюсь, вы уже знаете, как сопоставить диапазон по образцу. Если нет, проверьте ниже

lower..upper = 1..100

Здесь lower - 1, а upper - 100.

Реализация логики кода

Я просто написал модуль под названием Повторить, в котором есть функция с именем repeat/3, которая принимает параметры раз (количество раз): верхняя граница, ввод и function, чтобы повторить.

Надеюсь, вы уже знаете, как передать функцию в качестве входного параметра. Если нет, вы можете использовать &Module.function/arity для передачи и function.() для его вызова.

Чтобы упростить эту задачу, я передаю input как "blackode" и function как IO.inspect/1. Здесь моя цель - напечатать строку, которую я не пропустил ни разу.

Проверьте следующий код

defmodule Redo do
  def repeat(times, input, fun) when is_integer(times) and is_function(fun) do
    range = 0..times
    Enum.each(range, fn _ -> fun.(input) end)
  end
end

диапазон = 0.. раз

Эта строка кода определяет диапазон на основе переданного значения. Итак, я могу повторять функцию столько раз, сколько равно times. Ожидая, что 0..1 будет повторять функцию один раз, я так определил.

Но он повторял функцию times+1 раз.

iex> Redo.repeat(2, "blackode", &IO.inspect/1)
"blackode"
"blackode"
"blackode"
:ok

Почему это происходит?

Это происходит потому, что диапазон всегда включающий.

Это означает, что 0..1 установлен (0,1)collection. Поскольку мы используем диапазон как 0..2, это означает, что мы просто подготовили набор сбора (0, 1, 2) и выполняем перечисление по коллекции.

Вот в чем причина.

Итак, чтобы не повторять итерацию, я не могу просто передать диапазон как 0..0 , который все еще подготавливает набор сбора (0) и повторяется один раз.

Мы можем проверить количество диапазона, используя Enum.count/1

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

Как я понял, что итерация не повторяется?

Я использовал for понимание макросов вместо перечисления по диапазону и использования защитного предложения times > 0.

Итак, я заменил код

от:

Enum.each(range, fn _ -> fun.(input) end)

to:

for num <- range, num > 0, do: fun.(input)

Конечно, макрос for возвращает список. Мы все еще можем использовать Enum.each, используя сопоставление с образцом.

Enum.each(range, fn
  0 -> :do_nothing
  _ -> fun.(input)
end)

Теперь мы можем выполнять итераций ровно столько раз, сколько имеет значение верхней границы.

Всегда помните, что 0..0 означает не ничего это означает что-то набор (0)

Спасибо за уделенное время :)

Удачного кодирования :)

Оставайтесь здоровыми и кодируйте дольше

Удачного кодирования :)

Присоединяйтесь к нашему Telegram каналу Blackoders



«Blackoders
EAT 🍕 - CODE🐞 - SLEEP😴 Код, мысли и идеи Ресурсы по кодированию, советы, видео, статьи и новости Мы следим и собираем… t .меня"



Посетите репозиторий GitHub в разделе Советы по Killer Elixir

Рад, что вы можете внести свой вклад с помощью ★, чтобы он мог быстрее добраться до людей.