Значение по умолчанию может быть функцией, которая делает дорогой вызов. Если Map.get/3
не используется для возврата функций, вы можете проверить, является ли это значение функцией и вызывать его, если оно возвращается. Вроде так:
def default_value()
expensive_db_call()
end
def get_something(dict, key) do
case Map.get(dict, key, default_value) do
value when is_fun(value) ->
value.() # invoke the default function and return the result of the call
value ->
value # key must have existed, return value
end
end
Конечно, если карта содержит функции, этот тип решения, вероятно, не будет работать.
Также проверьте модуль Elixir's Stream. Хотя я не знаю, что это поможет решить вашу конкретную проблему, это позволяет ленивую оценку. Из документации:
Потоки являются составными, ленивыми перечислениями. Любой перечислимый, который генерирует элементы один за другим во время перечисления, называется потоком. Например, Range Эликсир является поток:
Более подробная информация доступна в документации: http://elixir-lang.org/docs/master/elixir/Stream.html
Рассматривая источник «задержки» в Clojure (здесь: https://github.com/clojure/clojure/blob/201a0dd9701e1a0ee3998431241388eb4a854ebf/src/jvm/clojure/lang/Delay.java), похоже, что задержка ближе к протоколу, чем макрос. Если бы я был вами, я бы исследовал протоколы в Elixir и продолжал таким образом. –
Я проверил источник 'delay', прежде чем задавать вопрос, и интересно, что' delay' была реализована в java, а не clojure, что позволяет использовать много разных конструкций и манипулировать выражением. – NhanH