Зачитать
Диапазон эликсира - странный опыт перечисления
Вы только незнакомец, пока не узнаете
В этой статье рассказывается об одном из моих странных опытов с Эликсиром.
Как я испытал?
В одном из моих проектов мне нужно повторять вызов функции определенное количество раз.
Сразу загорелась идея использовать дальность. Все мы знаем, что диапазон в 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
Рад, что вы можете внести свой вклад с помощью ★, чтобы он мог быстрее добраться до людей.