Эликсир - Псевдонимы
Чтобы облегчить повторное использование программного обеспечения, Elixir предоставляет три директивы: alias, require и import. Он также предоставляет макрос, называемый использованием, который кратко описан ниже -
# Alias the module so it can be called as Bar instead of Foo.Bar
alias Foo.Bar, as: Bar
# Ensure the module is compiled and available (usually for macros)
require Foo
# Import functions from Foo so they can be called without the `Foo.` prefix
import Foo
# Invokes the custom code defined in Foo as an extension point
use Foo
Давайте теперь подробно разберемся с каждой директивой.
псевдоним
Директива alias позволяет вам устанавливать псевдонимы для любого заданного имени модуля. Например, если вы хотите указать псевдоним'Str' в модуль String вы можете просто написать -
alias String, as: Str
IO.puts(Str.length("Hello"))
Вышеупомянутая программа генерирует следующий результат -
5
Псевдоним дается String модуль как Str. Теперь, когда мы вызываем любую функцию с помощью литерала Str, она фактически ссылается наStringмодуль. Это очень полезно, когда мы используем очень длинные имена модулей и хотим заменить их на более короткие в текущей области видимости.
NOTE - Псевдонимы MUST начинать с заглавной буквы.
Псевдонимы действительны только в пределах lexical scope они вызываются. Например, если у вас есть 2 модуля в файле и вы создаете псевдоним внутри одного из модулей, этот псевдоним не будет доступен во втором модуле.
Если вы даете имя встроенного модуля, например String или Tuple, в качестве псевдонима для какого-либо другого модуля, для доступа к встроенному модулю вам нужно будет добавить его с помощью "Elixir.". Например,
alias List, as: String
#Now when we use String we are actually using List.
#To use the string module:
IO.puts(Elixir.String.length("Hello"))
Когда вышеуказанная программа запускается, она генерирует следующий результат -
5
требовать
Эликсир предоставляет макросы как механизм для метапрограммирования (написания кода, генерирующего код).
Макросы - это фрагменты кода, которые выполняются и расширяются во время компиляции. Это означает, что для использования макроса мы должны гарантировать, что его модуль и реализация доступны во время компиляции. Это делается с помощьюrequire директива.
Integer.is_odd(3)
Когда вышеуказанная программа будет запущена, она выдаст следующий результат -
** (CompileError) iex:1: you must require Integer before invoking the macro Integer.is_odd/1
В Эликсире Integer.is_odd определяется как macro. Этот макрос можно использовать как охранник. Это означает, что для вызоваInteger.is_odd, нам понадобится модуль Integer.
Использовать require Integer функции и запустите программу, как показано ниже.
require Integer
Integer.is_odd(3)
На этот раз программа запустится и выдаст следующий результат: true.
Как правило, модуль не требуется перед использованием, за исключением случаев, когда мы хотим использовать макросы, доступные в этом модуле. Попытка вызвать макрос, который не был загружен, вызовет ошибку. Обратите внимание, что, как и директива alias, require также имеет лексическую область видимости . Подробнее о макросах мы поговорим в следующей главе.
импорт
Мы используем importдиректива для простого доступа к функциям или макросам из других модулей без использования полного имени. Например, если мы хотим использоватьduplicate функцию из модуля List несколько раз, мы можем просто импортировать ее.
import List, only: [duplicate: 2]
В этом случае мы импортируем только дубликат функции (с длиной списка аргументов 2) из List. Хотя:only является необязательным, его использование рекомендуется во избежание импорта всех функций данного модуля внутри пространства имен. :except также может быть предоставлен как опция для импорта всего в модуле, кроме списка функций.
В import директива также поддерживает :macros и :functions быть отдан :only. Например, чтобы импортировать все макросы, пользователь может написать:
import Integer, only: :macros
Обратите внимание, что импорт тоже Lexically scopedточно так же, как директивы require и alias. Также обратите внимание, что'import'ing a module also 'require's it.
использовать
Хотя это не директива, use это макрос, тесно связанный с requireчто позволяет вам использовать модуль в текущем контексте. Макрос использования часто используется разработчиками для добавления внешних функций в текущую лексическую область видимости, часто модулей. Давайте разберемся с директивой использования на примере -
defmodule Example do
use Feature, option: :value
end
Использование - это макрос, который преобразует вышеуказанное в -
defmodule Example do
require Feature
Feature.__using__(option: :value)
end
В use Module сначала требуется модуль, а затем вызывает __using__макрос в модуле. Elixir обладает прекрасными возможностями метапрограммирования и имеет макросы для генерации кода во время компиляции. Макрос _ _using__ вызывается в приведенном выше примере, и код внедряется в наш локальный контекст. В локальном контексте макрос использования был вызван во время компиляции.