З фоном з мов Python / Java / Golang, import
vs use
також був для мене плутаниною. Це пояснить механізм повторного використання коду з деякими прикладами декларативних мов.
імпорт
Словом, в Elixir вам не потрібно імпортувати модулі. Доступ до всіх публічних функцій можна отримати за допомогою повнокваліфікованого синтаксису MODULE.FUNCTION:
iex()> Integer.mod(5, 2)
1
iex()> String.trim(" Hello Elixir ")
"Hello Elixir"
У Python / Java / Golang вам потрібно import MODULE
використовувати функції в цьому МОДУЛІ, наприклад Python
In []: import math
In []: math.sqrt(100)
Out[]: 10.0
Тоді, що import
в Elixir може вас здивувати:
Ми використовуємо імпорт, коли хочемо легко отримати доступ до функцій або макросів з інших модулів, не використовуючи повноцінне ім'я
https://elixir-lang.org/getting-started/alias-require-and-import.html#import
Тож якщо ви хочете ввести sqrt
замість Integer.sqrt
, trim
замість String.trim
, import
допоможе
iex()> import Integer
Integer
iex()> sqrt(100)
10.0
iex()> import String
String
iex()> trim(" Hello Elixir ")
"Hello Elixir"
Це може спричинити проблеми з читанням коду, і коли існує конфлікт між іменами, тому він не рекомендується в Erlang (мові, яка впливає на Elixir). Але такої конвенції в Еліксирі немає, ви можете використовувати її на власний ризик.
У Python такий же ефект можна зробити:
from math import *
і рекомендується використовувати лише в деяких спеціальних сценаріях / інтерактивному режимі - для коротшого / швидшого набору тексту.
використовувати і вимагати
Що відрізняє use
/ require
відрізняється тим, що вони стосуються "макросу" - поняття, яке не існує в сім'ї Python / Java / Golang ....
Вам не потрібно, щоб import
модуль використовував його функції, але вам потрібно, щоб require
модуль використовував його макроси :
iex()> Integer.mod(5, 3) # mod is a function
2
iex()> Integer.is_even(42)
** (CompileError) iex:3: you must require Integer before invoking the macro Integer.is_even/1
(elixir) src/elixir_dispatch.erl:97: :elixir_dispatch.dispatch_require/6
iex()> require Integer
Integer
iex()> Integer.is_even(42) # is_even is a macro
true
Хоча це is_even
може бути записано як звичайна функція, це макрос, оскільки:
В Elixir Integer.is_odd / 1 визначається як макрос, щоб його можна було використовувати як захист.
https://elixir-lang.org/getting-started/alias-require-and-import.html#require
use
, уривок з документа Elixir:
Для використання потрібен даний модуль, а потім викликає __using__/1
зворотний виклик на ньому, що дозволяє модулю вводити деякий код у поточний контекст.
defmodule Example do
use Feature, option: :value
end
складається в
defmodule Example do
require Feature
Feature.__using__(option: :value)
end
https://elixir-lang.org/getting-started/alias-require-and-import.html#use
Отже, письмо use X
- це те саме, що писати
require X
X.__using__()
use/2
є макросом , макрос перетворить код в інший для вас код.
Ви захочете, use MODULE
коли:
- хочу отримати доступ до своїх макросів (
require
)
- І виконати
MODULE.__using__()
Випробуваний на Еліксирі 1.5
import Module
містить функції, які будуть використовуватися всередині вашого модуля.use Module
приносить функції, які слід використовувати, і відкриває їх публічно на вашому модулі